Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 49 additions & 48 deletions docs/subtitles-and-captions.html
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,7 @@

// Paced
const pacedPlayer = cloudinary.videoPlayer('paced', {
cloudName: 'demo',
autoplay: true,
muted: true
cloudName: 'demo'
});

const publicId = 'lincoln';
Expand Down Expand Up @@ -180,9 +178,7 @@

// Karaoke
const karaokePlayer = cloudinary.videoPlayer('karaoke', {
cloudName: 'demo',
autoplay: true,
muted: true
cloudName: 'demo'
});

karaokePlayer.source('lincoln', {
Expand Down Expand Up @@ -212,6 +208,22 @@
}
}
});

// Transcript from URL
const urlTranscriptPlayer = cloudinary.videoPlayer('url-transcript', {
cloudName: 'demo'
});

urlTranscriptPlayer.source('elephants', {
textTracks: {
captions: {
label: "Lincoln's Transcript",
url: 'https://res.cloudinary.com/demo/raw/upload/lincoln.transcript',
wordHighlight: true,
maxWords: 8
}
}
});
}, false);
</script>
</head>
Expand All @@ -227,8 +239,6 @@ <h3 class="mb-4">Subtitles & Captions</h3>
id="player"
playsinline
controls
muted
autoplay
class="cld-video-player cld-fluid"
crossorigin="anonymous"
width="500"
Expand All @@ -240,7 +250,6 @@ <h4 class="mt-4 mb-2">Playlist Subtitles (switch per source)</h4>
id="playlist"
playsinline
controls
muted
class="cld-video-player cld-fluid"
crossorigin="anonymous"
width="500"
Expand Down Expand Up @@ -290,7 +299,6 @@ <h4 class="mt-4 mb-2">Paced & Styled Captions</h4>
id="paced"
playsinline
controls
muted
class="cld-video-player cld-fluid"
crossorigin="anonymous"
width="500"
Expand All @@ -302,7 +310,17 @@ <h4 class="mt-4 mb-2">Karaoke player</h4>
id="karaoke"
playsinline
controls
muted
class="cld-video-player cld-fluid"
crossorigin="anonymous"
width="500"
></video>

<h4 class="mt-4 mb-2">Transcript from URL</h4>

<video
id="url-transcript"
playsinline
controls
class="cld-video-player cld-fluid"
crossorigin="anonymous"
width="500"
Expand All @@ -318,45 +336,16 @@ <h3 class="mt-4">Example Code:</h3>
&lt;video
id="player"
controls
muted
autoplay
class="cld-video-player"
crossorigin="anonymous"
width="500">
&lt;/video&gt;

&lt;video
id="playlist"
controls
muted
class="cld-video-player"
crossorigin="anonymous"
width="500"&gt;
&lt;/video&gt;

&lt;video
id="paced"
controls
muted
autoplay
class="cld-video-player"
crossorigin="anonymous"
width="500">
&lt;/video&gt;

&lt;video
id="karaoke"
controls
muted
autoplay
class="cld-video-player"
crossorigin="anonymous"
width="500">
&lt;/video&gt;
&lt;!-- ... a few more &lt;video&gt; tags --&gt;
</code>
<code class="language-javascript">

// Initialize player
// Initialize players
var player = cloudinary.videoPlayer('player', { cloud_name: 'demo' });

player.source(
Expand Down Expand Up @@ -443,9 +432,7 @@ <h3 class="mt-4">Example Code:</h3>

// Paced
const pacedPlayer = cloudinary.videoPlayer('paced', {
cloudName: 'demo',
autoplay: true,
muted: true
cloudName: 'demo'
});

pacedPlayer.source('lincoln', {
Expand Down Expand Up @@ -488,9 +475,7 @@ <h3 class="mt-4">Example Code:</h3>

// Karaoke
const karaokePlayer = cloudinary.videoPlayer('karaoke', {
cloudName: 'demo',
autoplay: true,
muted: true
cloudName: 'demo'
});

karaokePlayer.source('lincoln', {
Expand Down Expand Up @@ -521,6 +506,22 @@ <h3 class="mt-4">Example Code:</h3>
}
});

// Transcript from URL
const urlTranscriptPlayer = cloudinary.videoPlayer('url-transcript', {
cloudName: 'demo'
});

urlTranscriptPlayer.source('elephants', {
textTracks: {
captions: {
label: "Lincoln's Transcript",
url: 'https://res.cloudinary.com/demo/raw/upload/lincoln.transcript',
wordHighlight: true,
maxWords: 8
}
}
});

</code>
</pre>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/utils/cloudinary.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,13 @@ const isKeyInTransformation = (transformation, key) => {

const addTextTracks = (tracks, videojs) => {
tracks.forEach(track => {
if (track.src) {
if (track.src && track.src.endsWith('.vtt')) {
fetch(track.src, GET_ERROR_DEFAULT_REQUEST).then(r => {
if (r.status >= 200 && r.status <= 399) {
videojs.addRemoteTextTrack(track, true);
}
});
} else if (videojs.pacedTranscript) {
} else if (videojs.pacedTranscript && (!track.src || track.src.endsWith('.transcript'))) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how does it work? i do not see any mention of url property is it being translated somewhere to src?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, our original API was using url for VTTs, way before we added transcript support
https://github.com/cloudinary/cloudinary-video-player/blob/edge/src/video-player.js#L225

videojs.pacedTranscript(track);
}
});
Expand Down
17 changes: 14 additions & 3 deletions src/utils/get-analytics-player-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ const getCloudinaryOptions = (cloudinaryOptions = {}) => ({
posterOptionsPublicId: cloudinaryOptions.posterOptions && hasConfig(cloudinaryOptions.posterOptions.publicId)
});

const getTranscriptOptions = (textTracks = {}) => {
const tracksArr = [textTracks.captions, ...textTracks.subtitles];
return {
textTracks: hasConfig(textTracks),
pacedTextTracks: hasConfig(textTracks) && JSON.stringify(textTracks || {}).includes('"maxWords":') || null,
wordHighlight: hasConfig(textTracks) && JSON.stringify(textTracks || {}).includes('"wordHighlight":') || null,
transcriptAutoLoaded: tracksArr.some((track) => !track.url) || null,
transcriptFromURl: tracksArr.some((track) => track.url?.endsWith('.transcript')) || null,
transcriptLanguages: tracksArr.filter((track) => !track.url).map((track) => track.language || '').join(',') || null,
vttFromUrl: tracksArr.some((track) => track.url?.endsWith('.vtt')) || null
};
};

const getSourceOptions = (sourceOptions = {}) => ({
chapters: sourceOptions.chapters && (sourceOptions.chapters.url ? 'url' : 'inline-chapters'),
recommendations: sourceOptions.recommendations && sourceOptions.recommendations.length,
Expand All @@ -30,9 +43,7 @@ const getSourceOptions = (sourceOptions = {}) => ({
sourceInfoDescription: sourceOptions.info.description
} : {}),
...(sourceOptions.textTracks ? {
textTracks: hasConfig(sourceOptions.textTracks),
pacedTextTracks: hasConfig(sourceOptions.textTracks) && JSON.stringify(sourceOptions.textTracks || {}).includes('"maxWords":'),
wordHighlight: hasConfig(sourceOptions.textTracks) && JSON.stringify(sourceOptions.textTracks || {}).includes('"wordHighlight":'),
...(hasConfig(sourceOptions.textTracks) && getTranscriptOptions(sourceOptions.textTracks)),
...(sourceOptions.textTracks.options ? {
styledTextTracksTheme: sourceOptions.textTracks.options.theme,
styledTextTracksFont: sourceOptions.textTracks.options.fontFace,
Expand Down