Skip to main content

Stream selection

Some containers such as .m3u8 (and in the future .mpd) support multiple equivalent streams, of which you are supposed to select one.
For example, a .m3u8 file might contain multiple video streams with different resolutions.

By default, the stream with the highest resolution is selected (sorted by width multiplied by height).

Selecting a stream

Use the selectM3uStream option to select a stream.

tsx
import {parseMedia} from '@remotion/media-parser';
 
const media = await parseMedia({
src: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8',
selectM3uStream: ({streams}) => {
for (const stream of streams) {
console.log(stream.resolution); // {width: 1920, height: 1080}
console.log(stream.bandwidth); // 4400000
console.log(stream.url); // "https://test-streams.mux.dev/x36xhzz/193039199_mp4_h264_aac_hd_7.m3u8"
console.log(stream.averageBandwidth); // null
console.log(stream.codecs); // ["avc1.640028", "mp4a.40.2"]
console.log(stream.associatedPlaylists); // See below
}
 
return streams[0].id;
},
});

Show a stream selection interface

If you want an end user to pick the quality, it is recommended that you use two passes.
You can extract the streams in the first pass and then show a UI to the user to pick the quality.

tsx
import {parseMedia} from '@remotion/media-parser';
 
const {m3uStreams} = await parseMedia({
src: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8',
fields: {
m3uStreams: true,
},
});

Resorting to default behavior

If you want to resort to the default behavior (selecting the stream with the highest resolution), use the defaultSelectM3uStreamFn function.

tsx
import {parseMedia, defaultSelectM3uStreamFn} from '@remotion/media-parser';
 
const media = await parseMedia({
src: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8',
selectM3uStream: (params) => {
// Add custom logic
 
// ...
 
// Resort to default behavior
return defaultSelectM3uStreamFn(params);
},
});

Selecting an audio track

Once a primary stream has been selected, another callback may get invoked allowing you to pick an audio stream.

tsx
import {parseMedia} from '@remotion/media-parser';
 
const media = await parseMedia({
src: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8',
selectM3uAssociatedPlaylists: ({associatedPlaylists}) => {
return associatedPlaylists.filter((playlist) => {
// Information relayed from the .m3u8:
console.log(playlist.groupId); // string
console.log(playlist.language); // string | null
console.log(playlist.name); // string | null
console.log(playlist.autoselect); // boolean
console.log(playlist.default); // boolean
console.log(playlist.channels); // number | null
console.log(playlist.url); // string
 
return playlist.default;
});
},
});

The default behavior is to select the single associated playlist if there is only one, and otherwise select all associated playlists with the default: true attribute. The behavior is implemented by the filter function defaultSelectM3uAssociatedPlaylists.

tsx
import {parseMedia, defaultSelectM3uAssociatedPlaylists} from '@remotion/media-parser';
 
const media = await parseMedia({
src: 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8',
selectM3uAssociatedPlaylists: defaultSelectM3uAssociatedPlaylists,
});

Each M3uStream has a field stream.associatedPlaylists listing the associated audio tracks, which is useful for showing a UI for selecting the audio track.

See also