Closed arisprung closed 3 years ago
I'm no NDI/RTMP expert @arisprung but I have used @WalkerKnapp devolay in an app I have developed. But my understanding is that NDI is really just a transport mechanism for use over a LAN and you would need another means of consuming the NDI feed and send it to an RTMP endpoint. For instance in my case, my app can send the NDI content which I consume in vMix and which sends it to the RTMP endpoint. So the "SendVideoExample" just sends it "to" the LAN and you could check it is being sent by viewing it in Newtek's Studio Monitor which is included in their NDI 4 Tools.
Thanks @bdunkleysmith ! That clarifies alot! "SendVideoExample" is sending a sample stream and I can see the stream in my OBS - below sceenshot(similar to your Vmix). I am looking for a way to programmatically receive a NDI and send that stream to an RTMP endpoint. Any idea?
ok after further investigation I can use the "RecvExample" to retrive NDI . Any idea how to take the "DevolayVideoFrame" and "DevolayAudioFrame" and stream to RTMP ? Maybe FFMPEG?
Sorry @arisprung, that's way beyond my scope of knowledge. But perhaps @moster67 who had a joint interest in Issue #7 and I know is very knowledgeable in FFMPEG, may be able to provide some guidance if he's still active here.
Thx @bdunkleysmith appreciate your assistance!
@bdunkleysmith is right that NDI is just a transport, and that you'll need to convert from the raw video and auto given by DevolayVideoFrame
and DevolayAudioFrame
. I'd recommend javacpp-ffmpeg for this. It is essentially a 1-1 translation of the ffmpeg c api. I'm not very knowledgeable about the API, but there are a few published examples of streaming RTMP in C, and, even though it's not complete, you can cross reference how I use the Java api to save an NDI stream to a file. It is converting from NDI -> a saved video file, but that should translate fairly well to converting from NDI -> an RTMP stream.
(or, you might want to use a wrapper around JavaCPP, like ffmpeg4j. It will be easier to write, but it won't be as direct of a translation between C and Java)
Thx @WalkerKnapp ! This is great stuff! I started my research and ran the "RecordingExample" and got the below errors. Any idea?
Waiting for sources... Connecting to source: DESKTOP-GQNH46Q (Ari PC output) [file @ 0x7fa5e0e5db80] Setting default whitelist 'file,crypto,data' [mp4 @ 0x7fa5e130ae00] Could not find tag for codec none in stream #0, codec not currently supported in container Exception in thread "main" java.lang.IllegalStateException: Failed to write content header: Invalid argument at servlet.recording.JavaCPPDynamicRecorder.setup(JavaCPPDynamicRecorder.java:236) at servlet.recording.RecordingExample.main(RecordingExample.java:43)
Process finished with exit code 1
I just pushed an update that should fix this. I am definitely not an expert with ffmpeg, so let me know if there are any other issues.
Thx for your help. Getting the below error when running "RecordingExample":
Task :examples:RecordingExample.main() Connecting to source: DESKTOP-GQNH46Q (Ari PC output) [file @ 0x7fc1d394a4c0] Setting default whitelist 'file,crypto' [SWR @ 0x7fc1d7000000] Using fltp internally between filters x265 [info]: HEVC encoder version 0.0 x265 [info]: build info [Mac OS X][clang 8.1.0][64 bit] 8bit+10bit+12bit x265 [info]: using cpu capabilities: MMX2 SSE2Fast LZCNT SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2 x265 [info]: Main profile, Level-3.1 (Main tier) x265 [info]: Thread pool created using 8 threads x265 [info]: Slices : 1 x265 [info]: frame threads / pool features : 1 / wpp(12 rows) x265 [info]: Coding QT: max CU size, min CU size : 64 / 8 x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra x265 [info]: ME / range / subpel / merge : hex / 57 / 2 / 3 x265 [info]: Keyframe min / max / scenecut / bias: 1 / 250 / 40 / 5.00 x265 [info]: Lookahead / bframes / badapt : 20 / 4 / 2 x265 [info]: b-pyramid / weightp / weightb : 1 / 1 / 0 x265 [info]: References / ref-limit cu / depth : 3 / off / on x265 [info]: AQ: mode / str / qg-size / cu-tree : 2 / 1.0 / 32 / 1 x265 [info]: Rate Control / qCompress : CRF-28.0 / 0.60 x265 [info]: tools: rd=3 psy-rd=2.00 early-skip rskip signhide tmvp b-intra x265 [info]: tools: strong-intra-smoothing lslices=4 deblock sao
That's the normal output for it creating a recording. Did it crash after it displayed that? When you stop the source, it should stop on its own and write the output file.
I am going to go ahead and close this as stale for now. Feel free to reopen this if you have more information or if your solution didn't work out.
Is there any way I can send the NDI stream to an RTMP end point? I see the "SendVideoExample" but where is it sending to? I must be missing something here....