It would be a great feature to add basic authentication to the video source.
Passing the credentials directly in the link has been dropped by Chrome and more will follow
so http://userb:[email protected]/elon_musk_riding_horse_backwards.mp4 won't pass the credentials any more.
const options = {
headers: {
'Authorization': 'Bearer iaf87h8fhd8idfidf=='
},
tooltips: {
controls: true,
seek: true
},
controls: ['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'captions', 'settings', 'fullscreen']
};
this.videoPlayer = new Plyr(this.videoPlayerEl.nativeElement, options);
Passing a header to the HTTP request can open all sorts of posibilities for private video streaming
Does your example not achieve the same thing?
headers: {
'Authorization': 'Bearer iaf87h8fhd8idfidf=='
},
Headers property doesn't exist in the API. That was just my suggestion of who to do that
bumping this :)
bump :)
bump
bump
bump
Bumps won't speed it up. Someone contributing will though. Use those key strokes for good. I don't think this will be a quick change as it will involve loading the content manually rather than using the browsers in-built logic which opens a whole other can of worms.
Bumps won't speed it up. Someone contributing will though. Use those key strokes for good. I don't think this will be a quick change as it will involve loading the content manually rather than using the browsers in-built logic which opens a whole other can of worms.
Hey, I was able to solve this issue very easily using service workers, basically they act as a proxy and can inject custom headers.. even captures the requests required for playing the video.
Browser sends http requests to load the video (200 or 206) -> proxied by service worker's fetch handler -> add custom header -> Pass it normally without any efforts
Here's the service worker code i used to add an auth header:
File: ServiceWorker.js [register this in your main js file]
```
self.addEventListener("fetch", event => {
if (new URL(event.request.url).origin == "https://www.my_video_endpoint.com/") { //only add header to the endpoint i want
event.respondWith(customHeaderRequestFetch(event));
}
});
function customHeaderRequestFetch(event) {
const newRequest = new Request(event.request, {
mode: "cors",
credentials: "omit",
//also supports partial content (seeking)
headers: {
range:
event.request.headers.get("range") != undefined
? event.request.headers.get("range")
: "0-",
Authorization:
"Bearer " +"xxxABCDEFGHxxx"
}
});
return fetch(newRequest);
}
```
That's the whole code, now just register this service worker, and let the browser and plyr do all the hard work (automatically) :)
Reference: https://developers.google.com/web/fundamentals/primers/service-workers
I would be happy to send a PR but i am not familiar with the project structure yet. Hope anyone can implement this!
Thanks @Ashesh3! https://github.com/sampotts/plyr/issues/1312#issuecomment-677267757
For anyone who using Angular:
sw.js), place it in some where (e.g. src/assets/js/service-worker/). File content is:let domainInclude = ''; // Recieve from Component
let authToken = ''; // Recieve from Component
self.addEventListener('install', event => {
const params = new URL(location);
domainInclude = params.searchParams.get('include');
authToken = params.searchParams.get('token');
const installCompleted = Promise.resolve()
.then(() => {});
event.waitUntil(installCompleted);
});
self.addEventListener('activate', event => {
event.waitUntil(
self.clients.claim(),
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames.map((cache) => {
if (cache !== cacheName) {
return caches.delete(cache);
}
})
);
}));
});
// This function is implement from the guide of @Ashesh3
self.addEventListener('fetch', event => {
if (event.request.url.includes(domainInclude)) {
event.respondWith(customHeaderRequestFetch(event));
}
});
function customHeaderRequestFetch(event) {
const newRequest = new Request(event.request, {
mode: "cors",
credentials: "omit",
//also supports partial content (seeking)
headers: {
range:
event.request.headers.get("range") != undefined
? event.request.headers.get("range")
: "0-",
Authorization: authToken
}
});
return fetch(newRequest);
}
angular.json:projects > <your-pj-name> > architect > build > options > assets:"assets": [
..........
{
"glob": "**/*",
"input": "src/assets/js/service-worker/",
"output": "/"
}
..........
]
ngOnInit() {
if ('serviceWorker' in navigator) { // Make sure browser support Service Worker
navigator.serviceWorker.register(`/sw.js?include=${encodeURIComponent('<URL_MATCHING>')}&token=${<YOUR_TOKEN>}`, {
scope: '<SCOPE>'
})
.then(registration => registration.unregister());
// SW unregistered still working till page reload, so don't worry.
// But if you don't unregister here, Component may get stuck when you reload page,
// because old SW is fetching video and not done yet.
// In this case, If you stop playing video a while, page can be reload.
} else {
window.alert('Browser not support Service Worker.');
}
}
Note:
<URL_MATCHING>: Send to sw.js, using to check matching the endpoint you need to add Headers./api/video/: If Request URL include /api/video/ then sw.js will adding Headers to the request. (http://backend.local/api/video/aaaaa)<YOUR_TOKEN>: Token send to sw.js for attach to Headers.<SCOPE>: Router link where sw.js will working, e.g. /view-video/ (http://localhost:4200/view-video/aaaaa)
Most helpful comment
Bumps won't speed it up. Someone contributing will though. Use those key strokes for good. I don't think this will be a quick change as it will involve loading the content manually rather than using the browsers in-built logic which opens a whole other can of worms.