bentasker / HLS-Stream-Creator

Simple Bash Script to take a media file, segment it and create an M3U8 playlist for serving using HLS
BSD 3-Clause "New" or "Revised" License
273 stars 101 forks source link

Add prefix to routes #19

Closed JapSeyz closed 6 years ago

JapSeyz commented 6 years ago

Hey.

Would there be any interest in an -u command which could take a string or url to prefix the paths with?

We are experimenting with storing all our segments etc. in S3 for testing, and a CDN later-on, and the URL for the .key will not be just be /video.key as per #EXT-X-KEY:METHOD=AES-128,URI=video.key

So if we could supply a -u https://bucket.aws.com/videos/id_1/ which would prefix all routes in manifests like:

$name$_master.m3u8

EXT-X-STREAM-INF:BANDWIDTH=512000

$prefix$video_512.m3u8

$name$_$bitrate$.m3u8

EXT-X-KEY:METHOD=AES-128,URI=$prefix$video.key

My bash skills aren't superior, but I am sure I could cook something up if this would benefit the repo?

bentasker commented 6 years ago

I'm open to it being added, but by default players will treat paths as relative - so if you pass it https://bucket.aws.com/videos/id_1/manifest_master.m3u8 it'll prefix all subsequent references with that domain. Obviously if the manifest is going to be served from elsewhere, though, your suggestion would definitely be helpful.

Having it on the key line would be very useful though, as traditionally you'd store the key somewhere else (with some form of authentication on the access), so being able to prefix that with a keyserver URL would definitely be a plus.

So, it'd probably be worth adding 2 flags, one for the keyfile and one for the segments (and possibly sub manifests?)

JapSeyz commented 6 years ago

yeah perhaps a -k and -u for key and url.

I won't be able to dig into it before the beginning of November as I go on vacation tonight without a laptop, but when I'm back I'll look into it. It should be fairly simple.

I didn't know the paths would be relative, that's good to know and minimises the need for the -u, but it might still be nice to have?

1) declare a variable as an empty string. 2) if the flag is set, set the variable to that string. 3) Add the variable in front of any route

Perhaps a good Hacktoberfest PR?

bentasker commented 6 years ago

Yeah that approach sounds good to me. I'm not likely to get chance before November either in all honesty.

I think having the ability to prefix would definitely be nice, as it gives a bit more flexibility in how you deploy and serve. Personally I prefer to try and avoid absolute URLs in the manifest (as it means rewriting them if you move the content), but there are situations where it can also be very helpful.

JapSeyz commented 6 years ago

Yeah, I'll see if I can put someone on the task, as it shouldn't be all that difficult.

I get that absolute URLs should preferably stay out of a manifest, but when we use it for testing S3 with localhost replacement (Minio) or a permanent CDN that we control, it should be alright.

If you absolutely have to move the content, a global search/replace in the containing folder for all .m3u8 files shouldn't take too long, it'll probably exponentially longer to move the files.

bentasker commented 6 years ago

In the meantime, doesn't exactly roll off the tongue, but you should be able to do this to tell ffmpeg to write a URL into the manifests

FFMPEG_FLAGS="-hls_base_url http://foo.bar.example.invalid/mypath "
export FFMPEG_FLAGS
./hls-stream-creator.sh [args]

I've not tried it to check, but the ffmpeg docs suggest it should work - https://ffmpeg.org/ffmpeg-formats.html#hls-2 - it says append, but I assume they mean prepend as it makes no sense to have 001.tshttp://example.com

That won't help you with the keyfile though, but should simplify things (especially as when making changes you could add an option, and then just append -hls_base_url to the ffmpeg options.

If you absolutely have to move the content, a global search/replace in the containing folder for all .m3u8 files shouldn't take too long, it'll probably exponentially longer to move the files.

This is true, and it also has the advantage that you force anyone trying to proxy your media to also rewrite the manifests on the fly (or cache and rewrite them) so that you can use CORS headers on your "authorised" origin to limit where the media can be embedded. Not impossible (or that hard) for them to get past, but it at least raises the bar a bit

JapSeyz commented 6 years ago

Exactly, the FFMPEG_FLAGS could work until something is integrated into the package, but I think the main reason to integrate it would be to prefix the key.

Is it possible to change the output name of the key? That way I can save all the keys in a single directory which is locked with some authorisation, and simply name them with the video UUID, so UUID.key and UUID2.key would be in the same safe directory. (this can also be done with a simple mv command afterwards, but might also be valuable to have in the script?)

bentasker commented 6 years ago

Is it possible to change the output name of the key?

Yes and no. The name of the keyfile is based on the playlist prefix (-p) which defaults to 'video'. So you can set the playlist prefix (which'll also affect the name of your manifests). There isn't currently a way to change it independently though.

JapSeyz commented 6 years ago

Okay, I may look into that as well.

bentasker commented 6 years ago

Would definitely be useful to have, in something I've been building recently I've kept a static prefix between streams (to simplify processing elsewhere) so were I using keys it'd definitely require a bit of work to host them all in a single location.

JapSeyz commented 6 years ago

I don't doubt that. We could also split them out over a few servers, but store as many as possible behind the same authorisation.

That's why I'd like to name them according to UUIDv4, to prevent collisions, and our videos are already stored in directories with UUIDv4 names, so'd be fairly simple to give the key the same name, and match them up that way.

Simply so we know we should always look for the key at https://example.com/videos/keys/{uuid} and only if that is authorised, can we watch the stream.

JapSeyz commented 6 years ago

@bentasker I am closing this, it should be completed it pr #20

bentasker commented 6 years ago

Thanks. pr #20 has now been merged