3d0c/gmf

mp4s-to-flv.go produce wrong video length

c1ngular opened this issue · 15 comments

i tried runing mp4s-to-flv.go from examples, with bbb.mp4 file from same folder , unexpectedly , it produces a longer video than the original one , 01:00 -> 01:45 . also the produced audio and video seems out of sync .

@3d0c do you have any idea where might be gone wrong ? thanks

3d0c commented

@c1ngular Yes, you're right. I need some time to check it out.

@3d0c I tried set GOP size option for video encoder, but it did not work . Set frame rate to much larger number 40, seems reduce the output video length.

@3d0c
i am making some progress based on your wonderful work , just let you know . though i may hit on bigger problems .

i have managed to make transcode/resample/watermark work on bbb.mp4 file contained in your project based on the codes/ideas from your example files and some other ffmpeg c/c++ tutorials, it seems working fine , but as long as i tried to make it work on a living stream(e.g. rtmp://202.69.69.180:443/webcast/bshdlive-pc,tried others as well) , everything just gone totally corrupted.

i got errors like "Input contains (near) NaN/+-Inf" and others(some are CGO related, i can not remember it all ,cuz i have tried so many combination of decode/encode parameter settings )

i am trying to make a live streaming switcher with transcoding/watermark/resampling , even audio mix/merge enabled , i have spent last 2 weeks learning and trying , but i am stuck here .

thank you

3d0c commented

@c1ngular Hi.

I'll take a look at your code closely ASAP. But one question - what you really want to achieve?
You want to transcode a stream (rtmp/rstp), or you need to combine different video files together or what?
Yes, mp4s-to-flv.go has a problem with syncing, because it was just a an example of how to do that.
By the way, looking through your code i found this one
https://github.com/c1ngular/organicio/blob/master/main.go#L115
you do inctx.Free() and then you operate with it - it's not a big problem, but could yield a panic or SIGSEGV or whatever.

Just tell me your want to do and i'll try to help you with an example.

Thanks.

@3d0c thank you .
Let me explain my goals:

I am trying to make a live streaming switcher, I have couple of incoming live streams(via rtsp and rtmp, each contains video and audio both) with different video and audio settings, so I want to choose random one of these streams , transcode/resample/watermark it and send(via rtmp or rtsp ) it to a remote server . Called restreaming ?

I also want to add some bonus features if achievable :

1.Rotate outgoing stream by a specific interval e.g. 15 minutes

  1. Replace outgoing audio stream by some local mp3 files , mixing would be even better than replace in my case

But I am still struggling with transcoding/resampling incoming video/audio streams to a specified/uniform output settings e.g. h264/AAC with fixed parameters . I am not in control of incoming streams, it could be very different of video/audio codec/dimensions/sample rate .

Thank you again for your wonderful work and valuable time

3d0c commented

@c1ngular
Well, you've got a complex task... I would propose you not to write it from the scratch.
You need at least an RTMP/RTSP server in front of your transcoder.

Transcoding is hard, especially when you have random input.

So, i would propose you to see an SRS for handling RMPT streams + FFMPEG for transcoding. It's going to be more faster an reilable solution.

Also, keep in mind, that it's better to use GPU transcoding, because CPU can handle only 3-5 streams at once. So if you need more think about it.

@3d0c thank you for your advice

i hava a rtmp/rtsp server running locally already, but it is lack of transcoding/resampling/watermarking capabilities , i have tried to run ffmpeg binary to do the transcoding/watermarking/compressing for outgoing stream , it works fine .

but my use case requires more subtle controls of restreaming behavior , i will not transcode all incoming streams simultaneously , just the outgoing one stream will be transcoded/processed and send to a remote server , outgoing stream will be rotated/changed on a specific interval (15 minutes )

work flow will be : select ONE random stream from local rtmp/rtsp server -> transcode/watermark/resample the stream ->send it to remote server -> after 15 minutes -> stop sending the current stream -> select ANOTHER stream from local server -> transcode/watermark/resample the NEW stream ->send it to remote server

i want this transition to be as smoothy as possible , without noticeable interrupt/delay of outgoing stream( that's why i keep a reference of all incoming streams in my code , let it be prepared for use at anytime ) . so in order to make this whole process simple , i want to convert the whichever one outgoing stream to same codec with fixed/static options(parameters), so i can reuse same encoder/encoder context without stop/re-initialise it for each transition of outgoing stream, and outgoing stream will always be the same format settings for sake of simplicity .

i will use gpu to do the hard working part , so i keep decoder/encoder as an option in my code , so i can pass the hardware accelerated decoder/encoder on scene . this program will run on Raspberry PI 4 4GB .

further more , if achievable, i want to mix some mp3 audios into outgoing audio stream , instead of solely replacing the outgoing sound by some mp3 files .

this is a complicated case , is it ?
am i mistaken something here ?

Thank you again .

P.S. i have the whole application written in Go , so i want this transcoding/stream processing part done in Go as well , and your project is the most complete/Go-styled one among i found several by google searches , it is quite beginner friendly, so i want to stick with your project .

Nks commented

I've the same problem. Any updates on this?

3d0c commented

Hi, @c1ngular
Well. I can't write all this stuff instead of you, but will try to help. Let's start small:

  • first - i'll fix an audio syncing bug in mp4s-to-flv.go, so you could concat different inputs
  • tell me, how can i help you with your other problems -- please simplify. I've reread your posts, but there are too many things, which are going to need a lot of attention.
3d0c commented

@Nks Hi.
Exactly what? Concat files? Restreaming?

Nks commented

@3d0c I'm writing the package to convert the video from any format to mp4. When I'm using the example to convert any format to the mp4 it increasing the length of the video and video is not synced with the audio. e.g. if I converting the 1 min length video it increasing the length to 1 min 43 seconds. So, I'm not asking for provide full solution, but this will be really helpful provide documentation for the library for figure out where the problem is. As @c1ngular already said - changing the "Den" changing the speed of the video. Is there any documentation how to use the codec?

Nks commented

Also I found good example how to use the libav library. Maybe it will be helpful too. https://github.com/leandromoreira/ffmpeg-libav-tutorial/blob/master/3_transcoding.c

3d0c commented

@Nks Yeah, looks good - will try it ASAP. As far as i can see they are using "duration" syncing. I used to work with PTS. Anyway I'll check it out.

@Nks it's working if you set timebase for codec and outgoing stream/packet, unfortunately i don't have the code anymore . audio filter is working for static files too , but not for live stream (rtsp/rtmp) , not for me at least .

i am using ffmpeg executable to do the converting now , due to my use case is pretty complex, it would took me too much time and try-error steps to achieve what i have wanted.