sergey-dryabzhinsky / nginx-rtmp-module

NGINX-based Media Streaming Server
http://nginx-rtmp.blogspot.com
BSD 2-Clause "Simplified" License
1.02k stars 215 forks source link

FR: SCTE-35 support #232

Open ilyaevseev opened 7 years ago

ilyaevseev commented 7 years ago

What it should to do?

1) Watch for SCTE-35 labels in the main input stream 2) Write info to "#EXT-X-SCTE35" lines in m3u as described in http://www.scte.org/SCTEDocs/Standards/SCTE%2035%202016.pdf 3) Switch to alternate input stream for given duration 4) Return back to the main stream input

ut0mt8 commented 7 years ago

You want to catch scte35 from rtmp to hls ? I hack a bit in my branch and now have a working solution in dash. I think I had to implement it in hls rapidly , so...

ilyaevseev commented 7 years ago

You want to catch scte35 from rtmp to hls ?

Yes.

ut0mt8 commented 7 years ago

OK I think I can help you a bit. You should look at my code in the dash module.

The first part is to interpret the scte35 amf event from the rtmp flux.

It really depend on your rtmp injector (I use Elemental live server in my case). There are two example in my code (one for simple oncuepoint event, another for oncuepoint_scte35 providing more information, (on_cuepoint function, and oncuepoint_scte35).).

After you have to insert the EXT-X header in the m3u at the right place. And finally have a player who support it.

Good luck. The good news it's that is seems easier than it dash, because in the event have to be carier inband.

ilyaevseev commented 7 years ago

You should look at my code in the dash module.

It seems that your ngx_rtmp_dash_on_cuepoint_scte35 routine supports very limited attributes set. For example, here is an real RTMP stream parsed by rtmpdump:

DEBUG: RTMP_ClientPacket, received: notify 642 bytes
DEBUG: (object begin)
DEBUG: (object begin)
DEBUG: Property: <Name:               type, STRING: event>
DEBUG: Property: <Name:         parameters, OBJECT>
DEBUG: (object begin)
DEBUG: Property: <Name:        messageType, STRING: com.elementaltechnologies.scte35.1>
DEBUG: Property: <Name: splice_command_typ, NUMBER: 6.00>
DEBUG: Property: <Name:      pre_roll_time, NUMBER: 464086.21>
DEBUG: Property: <Name:        descriptors, OBJECT>
DEBUG: (object begin)
DEBUG: Property: <Name:        descriptor1, OBJECT>
DEBUG: (object begin)
DEBUG: Property: <Name: splice_descriptor_, NUMBER: 2.00>
DEBUG: Property: <Name: segmentation_event, NUMBER: 92001.00>
DEBUG: Property: <Name: segmentation_event, BOOLEAN:    FALSE>
DEBUG: Property: <Name: delivery_not_restr, BOOLEAN:    FALSE>
DEBUG: Property: <Name: web_delivery_allow, BOOLEAN:    TRUE>
DEBUG: Property: <Name: no_regional_blacko, BOOLEAN:    TRUE>
DEBUG: Property: <Name: archive_allowed_fl, BOOLEAN:    FALSE>
DEBUG: Property: <Name: device_restriction, NUMBER: 3.00>
DEBUG: Property: <Name: segmentation_durat, NUMBER: 60000.00>
DEBUG: Property: <Name: segmentation_upid_, NUMBER: 1.00>
DEBUG: Property: <Name: segmentation_upid_, NUMBER: 3.00>
DEBUG: Property: <Name:  segmentation_upid, STRING: 0x012345>
DEBUG: Property: <Name: segmentation_type_, NUMBER: 33.00>
DEBUG: Property: <Name:        segment_num, NUMBER: 0.00>
DEBUG: Property: <Name:  segments_expected, NUMBER: 0.00>
DEBUG: (object end)
DEBUG: (object end)
DEBUG: (object end)
DEBUG: (object end)
DEBUG: (object end)

It's skipped because "break_duration" field is missed and "descriptors" object is not recognized (I copied logging lines from NGX_OK branch):

2017/05/22 19:07:07 [info] 7737#7737: *2 dash : onCuepoint_scte35 : amf not understood : res='0', ts='20565', type='event', mtype='com.elementaltechnologies.scte35.1', sctype='6', scid='0', prgid='0', duration='0', avail_num='0', avail_expected='0', client: 10.20.30.40/rtmp/test1, server: ngx-relay

The complete nginx log according to this scte35 event is here: https://gist.github.com/ilyaevseev/85456f56070177e64e91aae3de23fb72

ut0mt8 commented 7 years ago

You seem to use elemental live as I am. I'm curious of what version and whats settings you use ? (send_cuepoint ? send_cuepoint_scte35 ? on the rtmp input panel)

To answer you, I decoded and parse what I receive/dump from my Elemental :) Unfortunately the code is not designed to easily parse unfixed AMF message... I'm not sure this is normalized format. Perhaps Elemental maps what he received from the scte35 signal from SDI ?

That said, It's straightforward to add the correct structure to match your current AMF message and to keep what you need.

Note : If I remind correctly Elemental live send two type of message. The first (the one I catch) is inserted at the beginning of the AD, and send the duration. There are subsequent messages I ignore, which indicate that the AD is always on, and the remaining time. I have to dig if these message indicate the timeline of the AD tunnel. It will be very helpful.