eyevinn / channel-engine Goto Github PK
View Code? Open in Web Editor NEWOpen Source FAST Channel Engine library based on VOD2Live technology
License: Apache License 2.0
Open Source FAST Channel Engine library based on VOD2Live technology
License: Apache License 2.0
When using consuo.tv as a live source (or another local instance of channel engine) the Safari web player fetches the first couple of live segments and manifests and then stops downloading new segments. This however works as expected in Chrome with the Eyevinn web player without any issues.
When using https://cph-p2p-msl.akamaized.net/hls/live/2000341/test/master.m3u8 as a source for live content everything works as expected in both Safari and in Chromium based browsers.
Hello,
I'm struggling to make channel-engine work, but with no luck, can someone point to me what I'm doing wrong, I followed the start guide:https://vod2live.docs.eyevinn.technology/, and think the steps are not complex, but this just does not work, Thank you!
2022-12-07T17:22:36.855Z engine-state-store Using MEMORY for non-shared state store (session, cacheTTL=1000)
2022-12-07T17:22:36.858Z engine-state-store Using MEMORY for non-shared state store (playhead, cacheTTL=1000)
2022-12-07T17:22:36.859Z engine-state-store Using MEMORY for non-shared state store (sessionLive, cacheTTL=1000)
2022-12-07T17:22:36.875Z engine-server Starting engine
2022-12-07T17:22:36.876Z engine-server Do we have any new channels?
2022-12-07T17:22:36.877Z engine-server Adding channel with ID myfirstchannel
2022-12-07T17:22:36.886Z engine-server Adding channel with ID myfirstchannel
(node:22827) [DEP0111] DeprecationWarning: Access to process.binding('http_parser') is deprecated.
(Use node --trace-deprecation ...
to show where the warning was created)
2022-12-07T17:22:36.899Z engine-server restify listening at http://[::]:8080
2022-12-07T17:22:36.905Z engine-session-live [myfirstchannel]: SessionLive-Playhead consumer started
2022-12-07T17:22:36.909Z engine-session [myfirstchannel]: Playhead consumer started:
2022-12-07T17:22:36.909Z engine-session [myfirstchannel]: diffThreshold=1000
2022-12-07T17:22:36.909Z engine-session [myfirstchannel]: maxTickInterval=10000
2022-12-07T17:22:36.909Z engine-session [myfirstchannel]: averageSegmentDuration=3000
2022-12-07T17:22:36.922Z engine-session [myfirstchannel]: state=VOD_INIT
2022-12-07T17:22:36.923Z engine-session [myfirstchannel]: got first VOD uri=https://maitv-vod.lab.eyevinn.technology/tearsofsteel_4k.mov/master.m3u8:0
2022-12-07T17:22:37.498Z engine-session [myfirstchannel]: first VOD loaded
2022-12-07T17:22:37.498Z engine-session [myfirstchannel]: 0,3.75,-3.75,0,0,0,0,0,0,3.75,-3.75,0,0,0,0,0,3.75,-3.75,0,0,0,0,0,0,3.75,-3.75,0,0,0,0,0,3.75,-3.75,0,0,0,0,0,0,3.75,-3.75,0,0,0,0,0,3.75,-3.75,0,0,0,0,0,0,3.75,-3.75,0,0,0,0,0,3
.75,-3.75,0,0,0,0,0,0,3.75,-3.75,0,0,0,0,0,3.75,-3.75,0,0,0,0,0,0,-4.75
2022-12-07T17:22:37.499Z engine-session [myfirstchannel]: 0,11.25,18.75,26.25,33.75,41.25,48.75,56.25,63.75,75,82.5,90,97.5,105,112.5,120,131.25,138.75,146.25,153.75,161.25,168.75,176.25,183.75,195,202.5,210,217.5,225,232.5,240,251.25,25
8.75,266.25,273.75,281.25,288.75,296.25,303.75,315,322.5,330,337.5,345,352.5,360,371.25,378.75,386.25,393.75,401.25,408.75,416.25,423.75,435,442.5,450,457.5,465,472.5,480,491.25,498.75,506.25,513.75,521.25,528.75,536.25,543.75,555,562.5,
570,577.5,585,592.5,600,611.25,618.75,626.25,633.75,641.25,648.75,656.25,663.75,666.5
2022-12-07T17:22:37.506Z engine-session [myfirstchannel]: INCREMENT (mseq=1) vodMediaSeq=(1_1 of 85)
2022-12-07T17:22:37.506Z engine-session [myfirstchannel]: current[1]_prev[null]
2022-12-07T17:22:37.506Z engine-session [myfirstchannel]: current-offset[0]_prev-offset[null]
2022-12-07T17:22:37.509Z engine-session [myfirstchannel]: Current delta time (1): 3.75
2022-12-07T17:22:37.510Z engine-session [myfirstchannel]: Delta time is != 0 need will adjust 3.75sec to tick interval. tick=6.1530000000000005
2022-12-07T17:22:37.510Z engine-session [myfirstchannel]: Current playhead position (1): 11.25
2022-12-07T17:22:37.511Z engine-session [myfirstchannel]: 11:11250:+11239ms
2022-12-07T17:22:37.511Z engine-session [myfirstchannel]: Playhead stepping msequences too early. Need to wait longer. adding 10.239s
2022-12-07T17:22:37.511Z engine-session [myfirstchannel]: Requested tickInterval=16.392000000000003s (max=10s, diffThreshold=1000msec)
2022-12-07T17:22:37.511Z engine-session [myfirstchannel]: (2022-12-07T17:22:37.511Z) 0.597sec in increment. Next tick in 10 seconds
2022-12-07T17:22:39.902Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 3000ms
2022-12-07T17:22:39.906Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:22:39.906Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:22:41.913Z engine-server MONITOR: (2022-12-07T17:22:41.913Z) [myfirstchannel]: playhead: running
2022-12-07T17:22:41.913Z engine-server MONITOR: (2022-12-07T17:22:41.913Z) [myfirstchannel]: live-playhead: running
2022-12-07T17:22:42.905Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2997ms
2022-12-07T17:22:42.906Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:22:42.906Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:22:45.905Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2999ms
2022-12-07T17:22:45.906Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:22:45.906Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:22:46.910Z engine-server MONITOR: (2022-12-07T17:22:46.910Z) [myfirstchannel]: playhead: running
2022-12-07T17:22:46.911Z engine-server MONITOR: (2022-12-07T17:22:46.911Z) [myfirstchannel]: live-playhead: running
2022-12-07T17:22:47.465Z engine-session [myfirstchannel]: state=VOD_PLAYING (1_1, 85)
2022-12-07T17:22:47.468Z engine-session [myfirstchannel]: INCREMENT (mseq=2) vodMediaSeq=(2_2 of 85)
2022-12-07T17:22:47.470Z engine-session [myfirstchannel]: Current delta time (2): -3.75
2022-12-07T17:22:47.470Z engine-session [myfirstchannel]: Delta time is != 0 need will adjust -3.75sec to tick interval. tick=-0.754
2022-12-07T17:22:47.470Z engine-session [myfirstchannel]: Current playhead position (2): 18.75
2022-12-07T17:22:47.470Z engine-session [myfirstchannel]: 9970:18750:+8780ms
2022-12-07T17:22:47.471Z engine-session [myfirstchannel]: Playhead stepping msequences too early. Need to wait longer. adding 7.779999999999999s
2022-12-07T17:22:47.471Z engine-session [myfirstchannel]: Requested tickInterval=7.026s (max=10s, diffThreshold=1000msec)
2022-12-07T17:22:47.471Z engine-session [myfirstchannel]: (2022-12-07T17:22:47.471Z) 0.004sec in increment. Next tick in 7.026 seconds
2022-12-07T17:22:48.905Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2999ms
2022-12-07T17:22:48.905Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:22:48.906Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:22:51.905Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2999ms
2022-12-07T17:22:51.905Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:22:51.906Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:22:51.910Z engine-server MONITOR: (2022-12-07T17:22:51.910Z) [myfirstchannel]: playhead: running
2022-12-07T17:22:51.910Z engine-server MONITOR: (2022-12-07T17:22:51.910Z) [myfirstchannel]: live-playhead: running
2022-12-07T17:22:54.450Z engine-session [myfirstchannel]: state=VOD_PLAYING (2_2, 85)
2022-12-07T17:22:54.453Z engine-session [myfirstchannel]: INCREMENT (mseq=3) vodMediaSeq=(3_3 of 85)
2022-12-07T17:22:54.455Z engine-session [myfirstchannel]: Current delta time (3): 0
2022-12-07T17:22:54.456Z engine-session [myfirstchannel]: Current playhead position (3): 26.25
2022-12-07T17:22:54.456Z engine-session [myfirstchannel]: 16956:26250:+9294ms
2022-12-07T17:22:54.456Z engine-session [myfirstchannel]: Playhead stepping msequences too early. Need to wait longer. adding 8.294s
2022-12-07T17:22:54.456Z engine-session [myfirstchannel]: Requested tickInterval=11.289000000000001s (max=10s, diffThreshold=1000msec)
2022-12-07T17:22:54.456Z engine-session [myfirstchannel]: (2022-12-07T17:22:54.456Z) 0.005sec in increment. Next tick in 10 seconds
2022-12-07T17:22:54.906Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2999ms
2022-12-07T17:22:54.906Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:22:54.906Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:22:56.913Z engine-server MONITOR: (2022-12-07T17:22:56.913Z) [myfirstchannel]: playhead: running
2022-12-07T17:22:56.913Z engine-server MONITOR: (2022-12-07T17:22:56.913Z) [myfirstchannel]: live-playhead: running
2022-12-07T17:22:57.908Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 3000ms
2022-12-07T17:22:57.908Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:22:57.908Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:00.908Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2999ms
2022-12-07T17:23:00.909Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:00.909Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:01.914Z engine-server MONITOR: (2022-12-07T17:23:01.913Z) [myfirstchannel]: playhead: running
2022-12-07T17:23:01.914Z engine-server MONITOR: (2022-12-07T17:23:01.914Z) [myfirstchannel]: live-playhead: running
2022-12-07T17:23:03.909Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2999ms
2022-12-07T17:23:03.910Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:03.910Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:04.409Z engine-session [myfirstchannel]: state=VOD_PLAYING (3_3, 85)
2022-12-07T17:23:04.413Z engine-session [myfirstchannel]: INCREMENT (mseq=4) vodMediaSeq=(4_4 of 85)
2022-12-07T17:23:04.414Z engine-session [myfirstchannel]: Current delta time (4): 0
2022-12-07T17:23:04.415Z engine-session [myfirstchannel]: Current playhead position (4): 33.75
2022-12-07T17:23:04.415Z engine-session [myfirstchannel]: 26915:33750:+6835ms
2022-12-07T17:23:04.415Z engine-session [myfirstchannel]: Playhead stepping msequences too early. Need to wait longer. adding 5.835s
2022-12-07T17:23:04.416Z engine-session [myfirstchannel]: Requested tickInterval=8.83s (max=10s, diffThreshold=1000msec)
2022-12-07T17:23:04.416Z engine-session [myfirstchannel]: (2022-12-07T17:23:04.416Z) 0.005sec in increment. Next tick in 8.83 seconds
2022-12-07T17:23:06.912Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 3000ms
2022-12-07T17:23:06.913Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:06.913Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:06.916Z engine-server MONITOR: (2022-12-07T17:23:06.916Z) [myfirstchannel]: playhead: running
2022-12-07T17:23:06.916Z engine-server MONITOR: (2022-12-07T17:23:06.916Z) [myfirstchannel]: live-playhead: running
2022-12-07T17:23:09.913Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2999ms
2022-12-07T17:23:09.913Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:09.913Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:11.918Z engine-server MONITOR: (2022-12-07T17:23:11.918Z) [myfirstchannel]: playhead: running
2022-12-07T17:23:11.918Z engine-server MONITOR: (2022-12-07T17:23:11.918Z) [myfirstchannel]: live-playhead: running
2022-12-07T17:23:12.914Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 3000ms
2022-12-07T17:23:12.914Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:12.914Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:13.200Z engine-session [myfirstchannel]: state=VOD_PLAYING (4_4, 85)
2022-12-07T17:23:13.203Z engine-session [myfirstchannel]: INCREMENT (mseq=5) vodMediaSeq=(5_5 of 85)
2022-12-07T17:23:13.205Z engine-session [myfirstchannel]: Current delta time (5): 0
2022-12-07T17:23:13.205Z engine-session [myfirstchannel]: Current playhead position (5): 41.25
2022-12-07T17:23:13.205Z engine-session [myfirstchannel]: 35705:41250:+5545ms
2022-12-07T17:23:13.206Z engine-session [myfirstchannel]: Playhead stepping msequences too early. Need to wait longer. adding 4.545s
2022-12-07T17:23:13.206Z engine-session [myfirstchannel]: Requested tickInterval=7.539s (max=10s, diffThreshold=1000msec)
2022-12-07T17:23:13.206Z engine-session [myfirstchannel]: (2022-12-07T17:23:13.206Z) 0.006sec in increment. Next tick in 7.539 seconds
2022-12-07T17:23:15.914Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2999ms
2022-12-07T17:23:15.915Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:15.915Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:16.920Z engine-server MONITOR: (2022-12-07T17:23:16.920Z) [myfirstchannel]: playhead: running
2022-12-07T17:23:16.920Z engine-server MONITOR: (2022-12-07T17:23:16.920Z) [myfirstchannel]: live-playhead: running
2022-12-07T17:23:18.915Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2999ms
2022-12-07T17:23:18.915Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:18.915Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:20.699Z engine-session [myfirstchannel]: state=VOD_PLAYING (5_5, 85)
2022-12-07T17:23:20.701Z engine-session [myfirstchannel]: INCREMENT (mseq=6) vodMediaSeq=(6_6 of 85)
2022-12-07T17:23:20.703Z engine-session [myfirstchannel]: Current delta time (6): 0
2022-12-07T17:23:20.704Z engine-session [myfirstchannel]: Current playhead position (6): 48.75
2022-12-07T17:23:20.704Z engine-session [myfirstchannel]: 43204:48750:+5546ms
2022-12-07T17:23:20.704Z engine-session [myfirstchannel]: Playhead stepping msequences too early. Need to wait longer. adding 4.546s
2022-12-07T17:23:20.704Z engine-session [myfirstchannel]: Requested tickInterval=7.541s (max=10s, diffThreshold=1000msec)
2022-12-07T17:23:20.704Z engine-session [myfirstchannel]: (2022-12-07T17:23:20.704Z) 0.005sec in increment. Next tick in 7.541 seconds
2022-12-07T17:23:21.917Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 3000ms
2022-12-07T17:23:21.917Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:21.917Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:21.920Z engine-server MONITOR: (2022-12-07T17:23:21.920Z) [myfirstchannel]: playhead: running
2022-12-07T17:23:21.920Z engine-server MONITOR: (2022-12-07T17:23:21.920Z) [myfirstchannel]: live-playhead: running
2022-12-07T17:23:24.919Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 3000ms
2022-12-07T17:23:24.919Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:24.919Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:26.922Z engine-server MONITOR: (2022-12-07T17:23:26.922Z) [myfirstchannel]: playhead: running
2022-12-07T17:23:26.922Z engine-server MONITOR: (2022-12-07T17:23:26.922Z) [myfirstchannel]: live-playhead: running
2022-12-07T17:23:27.921Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 3000ms
2022-12-07T17:23:27.921Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:27.921Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:28.200Z engine-session [myfirstchannel]: state=VOD_PLAYING (6_6, 85)
2022-12-07T17:23:28.202Z engine-session [myfirstchannel]: INCREMENT (mseq=7) vodMediaSeq=(7_7 of 85)
2022-12-07T17:23:28.204Z engine-session [myfirstchannel]: Current delta time (7): 0
2022-12-07T17:23:28.205Z engine-session [myfirstchannel]: Current playhead position (7): 56.25
2022-12-07T17:23:28.205Z engine-session [myfirstchannel]: 50705:56250:+5545ms
2022-12-07T17:23:28.205Z engine-session [myfirstchannel]: Playhead stepping msequences too early. Need to wait longer. adding 4.545s
2022-12-07T17:23:28.205Z engine-session [myfirstchannel]: Requested tickInterval=7.538s (max=10s, diffThreshold=1000msec)
2022-12-07T17:23:28.205Z engine-session [myfirstchannel]: (2022-12-07T17:23:28.205Z) 0.007sec in increment. Next tick in 7.538 seconds
2022-12-07T17:23:30.921Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2999ms
2022-12-07T17:23:30.922Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:30.922Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:31.923Z engine-server MONITOR: (2022-12-07T17:23:31.923Z) [myfirstchannel]: playhead: running
2022-12-07T17:23:31.923Z engine-server MONITOR: (2022-12-07T17:23:31.923Z) [myfirstchannel]: live-playhead: running
2022-12-07T17:23:33.923Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 3000ms
2022-12-07T17:23:33.923Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:33.923Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:35.698Z engine-session [myfirstchannel]: state=VOD_PLAYING (7_7, 85)
2022-12-07T17:23:35.700Z engine-session [myfirstchannel]: INCREMENT (mseq=8) vodMediaSeq=(8_8 of 85)
2022-12-07T17:23:35.702Z engine-session [myfirstchannel]: Current delta time (8): 0
2022-12-07T17:23:35.702Z engine-session [myfirstchannel]: Current playhead position (8): 63.75
2022-12-07T17:23:35.702Z engine-session [myfirstchannel]: 58202:63750:+5548ms
2022-12-07T17:23:35.703Z engine-session [myfirstchannel]: Playhead stepping msequences too early. Need to wait longer. adding 4.548s
2022-12-07T17:23:35.703Z engine-session [myfirstchannel]: Requested tickInterval=7.543s (max=10s, diffThreshold=1000msec)
2022-12-07T17:23:35.703Z engine-session [myfirstchannel]: (2022-12-07T17:23:35.703Z) 0.005sec in increment. Next tick in 7.543 seconds
2022-12-07T17:23:36.873Z engine-server Do we have any new channels?
2022-12-07T17:23:36.874Z engine-server Have any channels been removed?
2022-12-07T17:23:36.923Z engine-server MONITOR: (2022-12-07T17:23:36.923Z) [myfirstchannel]: playhead: running
2022-12-07T17:23:36.924Z engine-server MONITOR: (2022-12-07T17:23:36.924Z) [myfirstchannel]: live-playhead: running
2022-12-07T17:23:36.924Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2999ms
2022-12-07T17:23:36.924Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:36.925Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:39.924Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2999ms
2022-12-07T17:23:39.925Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
2022-12-07T17:23:39.925Z engine-server [myfirstchannel]: streamSwitcher returned switchstatus=false
2022-12-07T17:23:41.926Z engine-server MONITOR: (2022-12-07T17:23:41.925Z) [myfirstchannel]: playhead: running
2022-12-07T17:23:41.926Z engine-server MONITOR: (2022-12-07T17:23:41.926Z) [myfirstchannel]: live-playhead: running
2022-12-07T17:23:42.924Z engine-server StreamSwitchLoop waited for all channels. Next tick in: 2999ms
2022-12-07T17:23:42.925Z engine-stream-switcher [myfirstchannel]: No streamSwitchManager available
It should be possible to define a channel to passthrough closed-captions where the captions are in-stream in the source VODs, e.g.
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS,GROUP-ID="CC",LANGUAGE="eng",NAME="english",INSTREAM-ID="CC1"
#EXT-X-STREAM-INF:BANDWIDTH=9779208,AVERAGE-BANDWIDTH=8951586,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=24.000,CLOSED-CAPTIONS="CC"
Support mixing over to a live stream when VOD2live channel is in an ad break.
This might be achieved by always signalling a return from break (CUE-IN) when mixing over to live, but needs to be validated that this is an ok scenario for various SSAI vendors.
A bug was discovered where the same source segment was appended twice to the Session-Live output m3u8.
Normally, we expect a Live source HLS stream to always increment the Mseq after a certain amount of time.
However, for sources using CDNs or other causes of desynchronized media manifests, subsequent Media manifests could have a decrement in Mseq value instead.
Now if the proceeding media manifest would contain a Mseq value 2 counts larger than the previous Mseq value then, Session-Live would have appended a source segment it should have not appended.
eg.
Session-Live fetches Live Source Media M3U8 with Mseq=9, we set prevMseq=9, increment finished,
Session-Live fetches Live Source Media M3U8 with Mseq=10, we set prevMseq=10,
then on the next playhead ping,
Session-Live fetches Live Source Media M3U8 with Mseq=9. (Possible if a source uses unsynced CDN)
Then the number of selected segments from the Media playlist to append to the Session-Live output manifest will be calculated as
9
- 10
= -1
, which means NOT to append anything... at which point the prev Mseq will be set back to 9
.
then on the next playhead ping,
Session-Live fetches Live Source Media M3U8 with Mseq=11, the number of selected segments from the Media playlist to append to the Session-Live output manifest will be calculated as
11
- 9
= 2
, <-- (should be 1) This looks like we went from 9 to 11, but we already got 10 before.
When no slate is defined, the Promise should be rejected as well as debugging. Also applies to the situation where loading a slate fails.
An issue arises when nodes switch to live and a Follower node, gets stuck in the
"ALERT! Live Source Data NOT in sync! Will try again after X ms"
loop for a while.
Now, what should happen is that the Follower would have received a Live manifest that is ahead of what the Leader got when it first requested for a live manifest.
When this happens the engine will have the Follower 'drop' its manifest and use the live segments that the Leader stored in Redis instead.
This will ensure that, even though the Follower was slower in getting the correct segments, both nodes are in sync and will create the same manifests.
The Issue comes when the follower node's playhead tick interval is too long after this, relative to the live source tick interval.
By default, the tick interval is 6 seconds on the first round. Furthermore, if there was a live source fetch desync, then the tick interval would be the full 6 seconds. Normally, the tick interval time would subtract the time it took to fetch the live manifest.
During this long tick time, the leader could have already gone for another round of live segments before the follower could even read from the store. This results in the Follower missing a vital round of stored live segments, and becoming desynced with the Leader.
The preroll could be specified in the channel manager through a function that either fetch from some endpoint -> the slate URI or directly provides it in the code
It should be possible to let the preroll mixing happen in stream_switcher.js
When the leader fails to load next VOD and instead loads a slate the current VOD in the Redis db is not updated causing the two nodes to be out of sync. The other node is playing but the wrong VOD.
Leader node:
2021-06-16T07:37:04.047Z engine-session [6]: state=VOD_PLAYING (46_46, 48)
2021-06-16T07:37:04.062Z engine-session [6]: INCREMENT (mseq=40278) vodMediaSeq=(47_47 of 48)
2021-06-16T07:37:04.067Z engine-session [6]: I am the leader and updated tick interval to 4 sec
2021-06-16T07:37:04.072Z engine-session [6]: state=VOD_NEXT_INIT
2021-06-16T07:37:04.150Z engine-session [6]: got next VOD uri=https://virtual-channels-functions-alb.b17g-stage.net/stitch/master.m3u8?payload=eyJ1cmkiOiJodHRwczovL2xicy11c3AtaGxzLXZvZC5jbW9yZS5zZS92b2QvMTRmMGMvVmlsbF92aV9zYW1tYV9zYWtjYzExXzEzKDEzMzEwODA2X0lTTVVTUCkuaXNtL1ZpbGxfdmlfc2FtbWFfc2FrY2MxMV8xMygxMzMxMDgwNl9JU01VU1ApLm0zdTg/aGxzX25vX211bHRpcGxleD1mYWxzZSZmaWx0ZXI9KHR5cGUhPVwidGV4dHN0cmVhbVwiKSIsImJyZWFrcyI6W3sicG9zIjowLCJkdXJhdGlvbiI6MzAwMCwidXJsIjoiaHR0cHM6Ly90cmFpbGVyLWFkbWluLWNkbi5iMTdnLXN0YWdlLm5ldC9obHMvNjAyZjg3ZjY2MmFkMzMwMDIyNmIyNWE5L2luZGV4Lm0zdTgifSx7InBvcyI6MCwiZHVyYXRpb24iOjIwMDAwLCJ1cmwiOiJodHRwczovL3RyYWlsZXItYWRtaW4tY2RuLmIxN2cubmV0L2hscy82MGFmODRiYjNiYzM5MzAwMjc4Y2MzOTYvaW5kZXgubTN1OCJ9LHsicG9zIjowLCJkdXJhdGlvbiI6NjAwMCwidXJsIjoiaHR0cHM6Ly90cmFpbGVyLWFkbWluLWNkbi5iMTdnLm5ldC9obHMvNjBhMjJhMmVjNmRkZjQwMDQ2ODE5YzI1L2luZGV4Lm0zdTgifSx7InBvcyI6MCwiZHVyYXRpb24iOjIwMDAwLCJ1cmwiOiJodHRwczovL3RyYWlsZXItYWRtaW4tY2RuLmIxN2cubmV0L2hscy82MDkxNWZhYmQ0YWQwNTAwNjc3NjhjM2QvaW5kZXgubTN1OCJ9LHsicG9zIjowLCJkdXJhdGlvbiI6MzAwMDAsInVybCI6Imh0dHBzOi8vdHJhaWxlci1hZG1pbi1jZG4uYjE3Zy5uZXQvaGxzLzYwYTIyN2Y2OGI5ZWUxMDAzZTNjMjNmNy9pbmRleC5tM3U4In0seyJwb3MiOjAsImR1cmF0aW9uIjo4MDAwLCJ1cmwiOiJodHRwczovL3RyYWlsZXItYWRtaW4tY2RuLmIxN2cubmV0L2hscy82MDk1NDcxZGQzNDNmYTAwNTI0ZTNjMmEvaW5kZXgubTN1OCJ9LHsicG9zIjowLCJkdXJhdGlvbiI6MzAwMDAsInVybCI6Imh0dHBzOi8vdHJhaWxlci1hZG1pbi1jZG4uYjE3Zy5uZXQvaGxzLzYwYzg4MzgzZDE4MmJhMDA4MmI5YmQ1ZS9pbmRleC5tM3U4In0seyJwb3MiOjAsImR1cmF0aW9uIjoyMDAwMCwidXJsIjoiaHR0cHM6Ly90cmFpbGVyLWFkbWluLWNkbi5iMTdnLm5ldC9obHMvNjBjMzY0MWZmOGUwNTIwMDQ5YmVhM2U5L2luZGV4Lm0zdTgifSx7InBvcyI6MCwiZHVyYXRpb24iOjMwMDAsInVybCI6Imh0dHBzOi8vdHJhaWxlci1hZG1pbi1jZG4uYjE3Zy1zdGFnZS5uZXQvaGxzLzYwMmY4N2Y2NjJhZDMzMDAyMjZiMjVhOS9pbmRleC5tM3U4In1dfQ==:0
[6]: Failed to init next VOD
2021-06-16T07:37:04.212Z engine-session [6]: ReferenceError: masterManifestUri is not defined
[6]: Will insert slate
2021-06-16T07:37:04.271Z engine-session [6]: slate loaded
2021-06-16T07:37:04.312Z engine-session [6]: INCREMENT (mseq=40232) vodMediaSeq=(1_1 of 7)
Follower node:
2021-06-16T07:37:04.341Z engine-session [6]: state=VOD_PLAYING (1_1, 48)
2021-06-16T07:37:04.346Z engine-session [6]: INCREMENT (mseq=40232) vodMediaSeq=(1_1 of 48)
2021-06-16T07:37:04.347Z engine-session [6]: Current delta time (1): 0
2021-06-16T07:37:04.348Z engine-session [6]: Current playhead position (1): 4
2021-06-16T07:37:04.348Z engine-session [6]: 190461:4000:-186461ms
2021-06-16T07:37:04.348Z engine-session [6]: Requested tickInterval=-178.46800000000002s (max=6s, diffThreshold=4000msec)
2021-06-16T07:37:04.348Z engine-session [6]: (2021-06-16T07:37:04.348Z) 0.007sec in increment. Next tick in 0.5 seconds
2021-06-16T07:37:04.800Z engine-session [6]: state=VOD_PLAYING (2_2, 48)
2021-06-16T07:37:04.801Z engine-session [6]: INCREMENT (mseq=40233) vodMediaSeq=(2_2 of 48)
2021-06-16T07:37:04.802Z engine-session [6]: Current delta time (2): 0
2021-06-16T07:37:04.802Z engine-session [6]: Current playhead position (2): 8
2021-06-16T07:37:04.802Z engine-session [6]: 190915:8000:-182915ms
2021-06-16T07:37:04.802Z engine-session [6]: Requested tickInterval=-174.918s (max=6s, diffThreshold=4000msec)
2021-06-16T07:37:04.802Z engine-session [6]: (2021-06-16T07:37:04.802Z) 0.003sec in increment. Next tick in 0.5 seconds
2021-06-16T07:37:05.254Z engine-session [6]: state=VOD_PLAYING (2_2, 48)
2021-06-16T07:37:05.256Z engine-session [6]: INCREMENT (mseq=40233) vodMediaSeq=(2_2 of 48)
There seems to be an issue where the channel engine does not fetch a new live manifest fast enough every time. This results in a small stuttering lasting about 1 second. This occurs maybe once or twice per hour when using this as a schedule source https://schedule.vc.eyevinn.technology/api/v1
.
This needs to be further investigated to more precisely determine the cause and how to fix it.
In HA mode, eg running 2 instances with 1 redis, Follower node stopped shifting seg-items correctly from internal vodSegments list.
Currently in stream_switcher.js we extract the schedule from the streamSwitchManager
through the function getSchedule()
.
We need to extend this function and stream_switcher.js to handle getting channel-specific schedules, i.e.
await this.streamSwitchManager.getSchedule(this.sessionId);
Finally, the actual function in reference StreamSwitchManager needs to be updated to handle this new input argument.
Currently, the manifests returned from sessionLive.js, slide the window of playlist segments based on item count.
eg. if target_count is 10 and 2 new segments are added, then sessionLive will release the 2 top-most segments.
Media-Sequence increments by 2.
This is different from how session.js (hls-vodtolive) does it, where it releases segments based on the total segment duration of all segments in the playlist.
eg. if target_duration is 60s. Current playlist contains 10 segments each 6s long, and 2 new segments (3s duration each) are added to the playlist, then only 1 top-most segment would be released since: 60 + 3 + 3 - 6 = target_duration
Media-Sequence increments by 1.
Having different rules in session and sessionLive poses some issues when mix-switching back, if the durations of the segments in v2l are much shorter than live
Suggest implementing the same rules in sessionLive as in session!
We need an alternative for getting the engine's master, media & audio manifests that do not involve the server end-points.
These manifest can be generated directly in new functions in server.js
i.e
async engine.getMasterManifest(channelId)
async engine.getMediaManifests(channelId)
async engine.getAudioManifests(channelId)
Note, the latter 2 functions should return an object containing all media/audio manifests.
Currently we are not logging the cause of the error when we validate the uri before switching to live.
Update documentation with instructions and examples on how to control the stream switcher.
Provide an example of a Switch manager with an API POST endpoint /breaking
. When a POST is issued with a URL to a live HLS stream the switcher will instantly switch to this live-stream.
Support for handling VOD that has CMAF segments
When switching to either vod2live or live2live, a client may receive a manifest from the engine that has different segment URLs because the segment URLs are for a different variant than the manifest from before. This is due to the fact that SessionLive (which has a manifest builder function in it) chooses/filters variants differently from Session, which actually uses a function in @eyevinn/hls-vodtolive
when filtering and building manifests.
Suggest adding the same choosing logic to SessionLive's function.
Non-Critical Issue, but some players may make an OPTIONS request when fetching the m3u8 files from CE. Could be able to handle those requests.
HLS player stops after 2-3 videos for HLS stream which has demuxed audio with a slightly different #EXINF values: for video it is 6.006 while for audio it is 6.016.
You can reproduce it using these two manifests:
https://amsrmpdevwe-euwe.streaming.media.azure.net/94f0df66-d92d-4d21-815a-756a2a00d186/5882_b4d.ism/manifest(format=m3u8-aapl)
https://amsrmpdevwe-euwe.streaming.media.azure.net/5237a941-7d05-4c56-82bd-c4f51322b43e/5614_0a0.ism/manifest(format=m3u8-aapl)
I've checked videos from your server-demuxed.js demo script and found that audio and video segments durations are equal. So I suspect that there is a root cause. But I am not sure.
We need to ensure that ad markers (cue out/in tags) are preserved and passed through from both vod2live and live source in v3.
Add support for memcached in addition to Redis as shared session storage
In a ChannelEngine's engineOptions
, when the maxTickInterval
is set lower than the largest expected segment duration - or when the largest segment duration is higher than the default maxTickInterval
of 10 seconds, then a playback issue may occur after some time.
When the maxTickInterval
is lower then the tickInterval
in session.startPlayheadAsync()
then the internal playhead tick interval duration will be set too low, depending on the difference between the tick and the maxTick.
This will result in incrementing the channel's v2l stream media-sequences too early. The playhead will know that it is too early and will try to compensate by extending the next tickInterval
, padding some extra time. However, it can not compensate as it is limited to the max value.
Consider the example of running the channel engine with assets with segments of 6000ms duration, and with a maxTickInterval set to 5000ms.
The channel-engine Playhead will step (or iterate) after 5000ms, when it should have done it after 6000ms. On the next iteration, depending on the set playheadDiffThreshold
value, the diff will be added to the next tick duration as an attempt to compensate and get in sync with the asset. e.i. 6000+1000=7000. But 7000 is also greater than the max and the tick interval will be lowered back to 5000ms.
On the next iteration, the Playhead will try to compensate by 2000ms, e.i. 6000+2000=8000. But again the max value will be used instead.
The difference will accumulate over time and the result will have the channel-engine step through media-sequences too fast, consuming the vod asset earlier than expected. An unwanted side-effect is that some players might not handle this livestream behavior gracefully and will just stop playback altogether.
Currently, when a session's streamSwitcher gets a rejection from
... = await this.streamSwitchManager.getSchedule(this.sessionId);
it is thrown to the top level at server.js to function
StreamSwitchLoop(...)
which doesn't handle rejection cases.
This could cause the function to end and thus no more calls to the streamSwitcher are made. Freezing the streamSwitch status
Currently, when LIVE and fetching live manifests for each variant of the live source stream, and the fetched manifests are not on the same media sequence, then it will fetch again EVERY variant manifest from the source until the served manifests are all matching in media sequence.
The problem is that it it does not keep any manifests from the previous tries. So what sometimes happens, and contributes to long time spent fetching, is that the media sequence for a variant might step again forcing another retry.
eg.
Fetched manifest media sequences -> [99, 99, 100]
Not lined up, try ALL variants again...
Fetched manifest media sequences -> [100, 99, 100]
Not lined up, try ALL variants again...
Fetched manifest media sequences -> [100, 100, 101]
Not lined up, try ALL variants again...
etc.
We should instead only fetch again the variants that have sequences lower than the max sequence.
Hi,
I've been working with the channel-engine to implement a vod-to-live service for our website. It seems like when the the channel-engine reaches the end of the feed, though, it just goes to slate and doesn't seem to be able to recover or loop. This is also true after I implemented a "schedule" which basically loops the vod library until it reaches 24 hours. In this case, the channel engine seems to go to slate after 24 hours.
Is there a flag for looping content, or some other method? Any help would be greatly appreciated.
Thank you!
We should have a documentation site including a quick start guide, tutorials etc
Channel Engine fails to start with node version 18 and bails with the following error
TypeError: Cannot set property closed of #<Readable> which has only a getter
at patch
Seems to be related to the NPM module restify
that is being used: restify/node-restify#1888
In order to better support typescript we should include type definitions of the external interface, either in the src repo or in https://github.com/DefinitelyTyped/DefinitelyTyped
A regression was introduced causing VOD with demuxed audio to no longer work
Currently, when switching from V2L->LIVE, the bumper-segments are stiched in between the V2L segments and the LIVE segments with a CUE-IN tag placed after the bumper segment.
This was not an expected nor wanted outcome because it would mean that the bumper segment is a part of the supposed AD break, which it isn't. This needs to be fixed!
However, on a LIVE->V2L switch, the CUE-IN tag is placed correctly (before the bumper segment)
Is it possible to generate Playlist on the go while live video source is available when ever we want to switch live source we can switch to.
Just like we normally do in rundown broadcast playout.
We are looking for a solution that can do playout live video source and inject commercials into live stream in user friendly manners.
Regards,
Fahad
Skype :sfahadshahzad
Though we set DURATION
on EXT-X-CUE-OUT
I am not sure if this is critical or a new issue that has been introduced in v3 but interesting to have a look at. When having VOD's with cue markers we get the following in the resulting vod2live stream:
https://maitv-vod.lab.eyevinn.technology/VINN.mp4/1000/1000-00012.ts
#EXTINF:1.240,
https://maitv-vod.lab.eyevinn.technology/VINN.mp4/1000/1000-00013.ts
#EXT-X-DISCONTINUITY
#EXTINF:11.000,
https://lab.cdn.eyevinn.technology/THE_GRAND_BUDAPEST_HOTEL_Trailer_2014.mp4/manifest_1_00001.ts
#EXT-X-CUE-IN
where the placement of EXT-X-CUE-IN
looks a bit strange. Maybe it is correct according to the standard but needs to be verified whether it shouldn't be placed before the
#EXTINF:11.000,
https://lab.cdn.eyevinn.technology/THE_GRAND_BUDAPEST_HOTEL_Trailer_2014.mp4/manifest_1_00001.ts
instead.
When using the /reset endpoint, currently only session is being reset. session-live and streamswitchers need to be reset too.
session-live already has a resetAsync() function. Just needs to call it in handler function.
streamswitcher statuses will need to set switcherStatus[channel] = null | false
to count as resetted
I've only been able to get this to work using a string like %28type%3D%3D"video"%2526%2526height<1000%29%2526%2526%28type%3D%3D"video"%2526%2526height>0%29
where you can see the double encoding of the ampersands %2526
Raw:
(type=="video"&&height<1000)&&(type=="video"&&height>0)
Pre encoded
(type=="video"%26%26height<1000)%26%26(type=="video"%26%26height>0)
Fully encoded
%28type%3D%3D"video"%2526%2526height<1000%29%2526%2526%28type%3D%3D"video"%2526%2526height>0%29
otherwise the express/req middleware breaks up
req.query['filter'] = "(type="video""
req.query['height<1000'] = '';
identified and confirmed in engine/server.js line 234
if (req.query['filter']) {
debug(Applying filter on master manifest ${req.query['filter']}
);
filter = filterQueryParser(req.query['filter']);
}
To simulate an event it should be possible to configure the engine to insert an EXT-X-ENDLIST
tag in the manifest [1]. If the engine is initiated with the option { event: true }
it will insert an EXT-X-ENDLIST at the end of the manifest when no new VOD is received by the nextVod()
call within an iteration.
Currently, in session.js, when adding extra time to the tick interval based on the external difference compensation, the rate is set to DIFF_CORRECTION_RATE
=0.5 and is hardcoded.
// Apply external diff compensation if available.
if (this.diffCompensation && this.diffCompensation > 0) {
const DIFF_COMPENSATION = (reqTickInterval * DIFF_CORRECTION_RATE).toFixed(2) * 1000;
debug(`[${this._sessionId}]: Adding ${DIFF_COMPENSATION}msec to tickInterval to compensate for schedule diff (current=${this.diffCompensation}msec)`);
tickInterval += (DIFF_COMPENSATION / 1000);
this.diffCompensation -= DIFF_COMPENSATION;
}
Would be better to have it be another engine option like forcedTargetDuration
so that it can be adjusted externally.
It should be possible to configure a channel to insert HLS-interstitial tags for a live ad break in a V2L channel. You configure ad serving endpoint to be used. The V2L channel also contains a slate for the as break that is either replaced downstream by SSAI or client side.
Currently, when SessionLive is fetching/loading media playlists from the live-source, and they do not all comeback with the same
#EXT-X-MEDIA-SEQUENCE
value, then they are to retry the manifest loading operation after waiting 1500ms.
However, for a source live stream with segment durations <4s, 1500ms might be too long, causing us to miss the window where the media playlists were all synced up.
eg.
... SessionLive fetches media playlist for all variants. Gets variant_1 w/ mseq:11, and variant_2 w/ mseq:12
... Not in sync! Try again after 1500ms
... SessionLive fetches media playlist for all variants. Gets variant_1 w/ mseq:12, and variant_2 w/ mseq:13
We missed the window when both were w/ mseq:12
I suggest that we have the time to wait depending on the duration of the newest Live source segment.
In order to support how AWS MediaTailor (SSAI) access the channel origin the following needs to be implemented.
Today a channel is accessed with the following URL: http://<engine>/live/master.m3u8?channel=1
and to adapt to MediaTailor an additional endpoint (alias) in the following form is needed http://<engine>/live/1/master.m3u8
which would translate to the same above.
Scheduled for next 2.minor-release which is currently main/master.
Currently the getSchedule() from the stream switch manager is called quite frequently. Reduce this frequency by changing the interval during an ongoing event. Around end of an event this frequency can be increased to handle late changes in schedule.
The currently playing VOD length is never added to the total mediasequence when loading a slate as next VOD. A slate caused by failing to load next VOD for example.
Recently we added try-catch blocks in the function _initSwitching(..)
To have manifest requesting clients wait for the _initSwitching(..)
to complete a switch, a boolean is set to true at the beginning of the switching process.
Now if a switch process fails, the error is caught and thrown to the upper levels. But right now the boolean is not set to false when this happens, fooling the StreamSwitcher into thinking _initSwitching(..)
is still busy processing a switch.
A proof-of-concept on how to apply DRM protection on a channel by adding the support for the playhead to push the generated manifest to an AWS MediaPackage channel.
Will introduce a separate service (probably another repo) that sits on the origin (or close) to and pull HLS (manifest and segments) and push to the origin.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.