lu-zero / bmdtools

Basic capture and play programs for Blackmagic Design Decklink
Boost Software License 1.0
198 stars 74 forks source link

Multiple Captures on Single Interface #90

Open PreDeToR opened 7 years ago

PreDeToR commented 7 years ago

Hi Guys

I am running into a bit of a problem, and I hope someone can help me out a bit or point me in the right direction.

Currently, I run bmdcapture which I then feed into ffmpeg/avconf to make a local copy of the feed and rtmp stream it to my remote servers. However I run into a issue sometimes when the connection to the servers drop the local file gets corrupted which means I cant use the file to retrieve the missed content.

Current Command (I know I am using FFMPEG, perfectly 99% of the time): /root/bmdtools/bmdcapture -C 4 -m 1 -A 2 -V 4 -M 5 -F nut -d 1 -v -f pipe:1 | /root/ffmpeg_sources/ffmpeg/ffmpeg -loglevel error -i pipe:0 -t 43200 -map_channel 0.1.0 -c:a mp3 -strict -2 -ac 2 -ar 44100 -ab 128k -af "volume=4" -deinterlace -pix_fmt yuv420p -vcodec libx264 -preset slow -coder 1 -bf 3 -x264opts nal-hrd=none -g 50 -b:v 3500k -bufsize 5500k -f flv 'rtmp://xxx/xxx/xxx'

What I want to do is: 1)run bmdcapture into a file or something (20-30 seconds backlog/buffer). 2)run a separate process to read this file and make a local backup. (for important streams that I need backups to in case the stream goes down) 3)run another process to then read the file from 1 and push that to my streaming servers. 4)possibly run another process to then read the file from 1 and push that to streaming servers using same of different flags(different audio mapping etc).

I thought of a FIFO/pipe but that only allows me one reading process. I also tried capturing in hls format (-f hls -hls_time 1 -hls_wrap 50 -hls_list_size 10) but then when 3 reads it and I stream it up I get this strange "hiccup" in the audio every 2 seconds or so.

Commands I used: /root/bmdtools/bmdcapture -C 4 -m 1 -A 2 -V 4 -M 2 -F nut -d 1 -v -f pipe:1 | /root/ffmpeg_sources/ffmpeg/ffmpeg -loglevel error -i pipe:0 -y -c:a mp3 -strict -2 -ac 2 -ar 44100 -ab 128k -deinterlace -pix_fmt yuv420p -vcodec libx264 -preset slow -coder 1 -bf 3 -x264opts nal-hrd=none -g 50 -b:v 3500k -bufsize 5500k -f hls -hls_time 1 -hls_wrap 50 -hls_list_size 10 -hls_segment_filename "/root/Streams/178F9BF0B9BA9DB813328A63F4A0F0A5-hls-%05d.ts" "/root/Streams/178F9BF0B9BA9DB813328A63F4A0F0A5-hls.m3u8"

/root/ffmpeg_sources/ffmpeg/ffmpeg -loglevel info -i "/root/Streams/178F9BF0B9BA9DB813328A63F4A0F0A5-hls.m3u8" -t 43200 -map_channel 0.1.0 -c:a mp3 -strict -2 -ac 2 -ar 44100 -ab 128k -af "volume=4" -pix_fmt yuv420p -vcodec libx264 -preset slow -coder 1 -bf 3 -x264opts nal-hrd=none -g 50 -b:v 3500k -bufsize 5500k -f flv 'rtmp://xxx/xxx/xxx'

So basically I want to grab the input from SDI, capture it on the machine locally with a small buffer, and then have 1 or more processes read from this local "buffer" to do other things with the stream.

Any Ideas, suggestions would be greatly appreciated.

Regards Danie

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/49279573-multiple-captures-on-single-interface?utm_campaign=plugin&utm_content=tracker%2F256764&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F256764&utm_medium=issues&utm_source=github).
msslava commented 6 years ago

PreDeToR, I also wanted to realize this. Have you found a solution?

PreDeToR commented 6 years ago

Hi @msslava

Yes I found a bit of a work-around, not the prettiest of solutions but it works.

What I Did was 1)Capture the stream and stream it to a file using mpegts (This allows reading and timestamping of the file while its being written to), This file/process is reset once a day. 2)I then have a script that gets the duration of the above file and starts as new ffmpeg process to stream using the timestamp so that I am always starting at the end of the file, I have two of these processes as I needed to stream to two different locations and pull the audio out the source stream differently as the one channel as english and the other french.

This works perfectly fine, it just uses some extra cpu.

msslava commented 6 years ago

Hi, PreDeToR! Thanks for you reply. An interesting idea with a temporary file. I want to record video from SDI and for me the main quality video. The mpegts can not this. How to be in this case? Can you share your scripts for reference?, for me it would be very useful. Thank you!

PreDeToR commented 6 years ago

@msslava

you can adjust the quality, my feeds aren't hd so its easy: 1) /root/bmdtools/bmdcapture -C 5 -m 1 -A 2 -V 4 -M 2 -F nut -d 1 -v -f pipe:1 | ffmpeg -loglevel error -i pipe:0 -y -c:a mp3 -strict -2 -ac 2 -ar 44100 -ab 128k -deinterlace -pix_fmt yuv420p -vcodec libx264 -preset slow -coder 1 -bf 3 -x264opts nal-hrd=none -g 25 -b:v 3500k -bufsize 8500k -f mpegts "/root/Streams/5.mp4"

The above script restarts once a day, and streams to the single file all day, so you just need to know how long the stream is , using ffprobe, to make sure you set the start time for your 2nd process

2) ffmpeg -loglevel info -re -ss 57 -t 43200 -i "/root/Streams/5.mp4" -map_channel 0.1.1 -c:a mp3 -strict -2 -ac 2 -ar 44100 -ab 128k -af "volume=4" -pix_fmt yuv420p -vcodec libx264 -preset slow -coder 1 -bf 3 -x264opts nal-hrd=none -g 50 -b:v 3500k -bufsize 5500k -f flv 'rtmp://xxx/xxx'

msslava commented 6 years ago

I mean, when we 1) write to mp4 and then 2) want to get from it in ProRes (for example) - it's wrong, I think. Thank you for sharing

PreDeToR commented 6 years ago

Ah, not sure about that i know ffmpeg can handle it for me, you might need something like a rtmp stream that you need to send to