Conversation
…nting out the ENFLIST if the playlistType is not available, since it's optional
…if it's not there, it is assumed to be a VOD
…gram-date-time isnt available
…rging a playlist with a tail of another
… concat, also added concat ability
…tes(), m3u.findDateGaps() and m3u.insertPlaylistItemsAfter()
…enamed all new functions to be more explicit, also added test for m3u.mergeByDate()
… minor date slicing bug
|
Wow, thanks for this. I'll be taking a closer look soon. |
```
{
"message": "createM3U is not defined",
"stack": "ReferenceError: createM3U is not defined\n at M3U.mergeByDate (/Users/akhoury/Perforce/akhoury_azizs-mac-mini_4287/speech/ramp/sites/m3u8-service/node_modules/m3u8/m3u.js:190:80)\n at /Users/akhoury/Perforce/akhoury_azizs-mac-mini_4287/speech/ramp/sites/m3u8-service/lib/index.js:295:24\n at tryCatchResolve (/Users/akhoury/Perforce/akhoury_azizs-mac-mini_4287/speech/ramp/sites/m3u8-service/node_modules/when/lib/apply.js:46:23)\n at callAndResolve (/Users/akhoury/Perforce/akhoury_azizs-mac-mini_4287/speech/ramp/sites/m3u8-service/node_modules/when/lib/apply.js:30:12)\n at callAndResolveNext (/Users/akhoury/Perforce/akhoury_azizs-mac-mini_4287/speech/ramp/sites/m3u8-service/node_modules/when/lib/apply.js:40:4)\n at tryCatchReject3 (/Users/akhoury/Perforce/akhoury_azizs-mac-mini_4287/speech/ramp/sites/m3u8-service/node_modules/when/lib/makePromise.js:856:7)\n at runContinuation3 (/Users/akhoury/Perforce/akhoury_azizs-mac-mini_4287/speech/ramp/sites/m3u8-service/node_modules/when/lib/makePromise.js:814:4)\n at Fulfilled.fold (/Users/akhoury/Perforce/akhoury_azizs-mac-mini_4287/speech/ramp/sites/m3u8-service/node_modules/when/lib/makePromise.js:588:4)\n at callAndResolve (/Users/akhoury/Perforce/akhoury_azizs-mac-mini_4287/speech/ramp/sites/m3u8-service/node_modules/when/lib/apply.js:34:12)\n at callAndResolveNext (/Users/akhoury/Perforce/akhoury_azizs-mac-mini_4287/speech/ramp/sites/m3u8-service/node_modules/when/lib/apply.js:40:4)"
}
```
|
Wow, these are awesome additions! I'd love to take advantage of all of these. If you need help reviewing to get this PR merged I would be glad to. I have this module used in production now and I'd love these new additions/fixes. |
|
I haven't had time yet. If you have time @blainsmith, it'd be appreciated. |
|
Great, I will poke around at it. If you ever need another maintainer I'd be glad to help out. I do rely on this plugin a lot so I would love it to stay alive. We are using it at http://oddnetworks.com |
|
So I found and issue with This is actually a VOD, but it is the |
|
Sounds good, I can add that in |
|
@bog, @blainsmith any more comments? and/or any idea when this would be merged? if accepted |
|
I could do with these new features as well :) |
|
I'm working on a fork for now so I have can point to it from a package.json file. Will switch it to point here when this is merged :) |
|
|
List of additions/changes (all backward compatible)
parser
optionsparameter tocreateStream(options)options.laxatrue/falseboolean which basically forgives the parsed text if it doesn't start by anEXTM3Utag, this is useful for merging many m3u8s into one, while tailing a large Live file.options.beforeItemEmit()a function hook which gets called before the emit of eachitemevent, passing thecurrentItemas the 1st argument. The reason this was useful in my use case is because I had m3u8s without the program-date-time tag, where the .ts files were named using timestamps, so before each item emit, I was doing something like thiscurrentItem.set('date', new Date(currentItem.get('uri')));- who knew thatffmpegdoes not support the inclusion ofEXT-X-PROGRAM-DATE-TIMEon each segment while generating m3u8s from a raw stream.parser['EXT-X-PROGRAM-DATE-TIME'](), sincem3u.toString()does output it if available but the current parser ignores it.m3u
m3u.clone()basically just returns a clone of them3uobject.m3u.concat()which behaves exactly like howm3u.merge()behaves but it returns a newm3uobject, basically just concats the playlist items.m3u.mergeByUri()to do a real unique merge, using eachitem.urias the identifier, returns a newm3uobjectm3u.mergeByDate()to do a real unique merge using eachitem.dateto find the stream gaps of stream-A and fill them in with slices of stream-B, returns a newm3uobjectm3uobject with a slice of the PlaylistItems. Also, slicing a live m3u while using an end-range, will make the returned m3u as VOD, since the slice has an ending.m3u.sliceByIndex(), (aliasm3u.slice()) slices based on the segments indices, returns a newm3uobjectm3u.sliceBySeconds(), slices based on the position of each segment on the timeline of video seconds duration, returns a newm3uobjectm3u.sliceByDates()slices based on the position of each segment on the timeline of real time (depends on theEXT-X-PROGRAM-DATE-TIMEtag of course, or a custom item.date being set via thebeforeItemEmithook), returns a newm3uobjectm3u.insertPlaylistItemsAfter([newItems], afterItem)m3u.findDateGaps()used bym3u.mergeByDate()m3u.sortByDate(), sorting is useful if you're merging un-ordered or random playlistsm3u.sortByUri()m3u.resetTargetDuration()which would either take anewTargetDurationto compare it and set it, or atrueboolean to re-check all thePlaylistItemsand figure out the max duration to use.m3u.isDateSupported()ENDLISTtag was actually found, then it's aVODsinceEXT-X-PLAYLIST-TYPEis optional and might not be there.m3u.isVOD()m3u.isLive()m3u.isMaster()if it's a master playlist or not.Notes
m3u.merge()should return a clone instead of mutating self, but that would be breaking change - OR if you prefer mutating self all the time, we can change all the other merging and slicing functions, i.e.m3u.slice*(), to mutate self as well instead of returning a clone, let me know what you think - I was just trying to mimic what the javascriptArraydoes when doing anarray.slice()orarray.concat(), both of these 2 return a newarray.Tests
I think I covered all the things I added :), still a little shy but I will submit more as I move along.