I also can’t get private videos to play on iOS using VideoJS and by setting the X-Token-Session
as described in Blog | Inserting custom headers.
See my Flask/jQuery/VideoJS implementation below.
let manifestUrl;
$.get('{{ url_for('video_view.get_video', video_id=video_id) }}')
.then((data) => {
manifestUrl = data.assets.hls;
return $.get(manifestUrl)
})
.then((data, status, request) => {
videojs.options.vhs.overrideNative = true;
videojs.Vhs.xhr.beforeRequest = (options) => {
options.headers = {
...options.headers,
"X-Token-Session": request.getResponseHeader('x-token-session')
};
return options;
};
})
.then(() => {
let player = videojs('my-video');
player.ready(() => {
player.controls();
player.src({
src: manifestUrl,
{#src: 'https://cdn.api.video/vod/vi4blUQJFrYWbaG44NChkH27/hls/manifest.m3u8',#}
type: 'application/x-mpegURL'
});
});
})
I get a 404
error which I’ve discovered means that the X-Token-Session
header is not set. After doing a bunch of research I learned that VideoJS uses Safari’s native HLS implementation.
This can be bypassed on macOS by setting videojs.options.vhs.overrideNative = true;
which in turn sets videojs.Vhs.xhr.beforeRequest
.
This is, however, not supported on iOS as there’s only partial support for MediaSource
which in turn means that videojs.Vhs.xhr.beforeRequest
is not called and the header is not set.
How can we set the header in Safari on iOS? How does the video.api player do it?