I have searched and found many similar questions, but not this one. I've experimented and can't come up with an answer.
I have a Standalone "Digital TV Converter Box". This receives broadcast TV, and can act as a DVR. Mine is a "viewtv", but it's available from dozens of different vendors. It records combined video and audio (and optionally closed captions / subtitles) into a BDAV format file. I want to watch the program on other platforms, and sometimes edit the file and separate programs, and the BDAV format is inconvenient (to say the least). ffmpeg can easily perform the first part of converting the file into something more useable:
ffmpeg -hide_banner -err_detect ignore_err -loglevel verbose -stats -i "channel09202022-0858.mts" -map 0 -c copy "channel-09202022-0858.m2ts"
Here is where my frustration starts. There is usually a delay between the video and audio file, and it's different every time. MediaInfo reports something this:
Audio
ID : 4352 (0x1100)
Menu ID : 1 (0x1)
Format : AC-3
Format/Info : Audio Coding 3
Commercial name : Dolby Digital
Codec ID : 129
Duration : 3 h 7 min
Bit rate mode : Constant
Bit rate : 192 kb/s
Channel(s) : 2 channels
Channel layout : L R
Sampling rate : 48.0 kHz
Frame rate : 31.250 FPS (1536 SPF)
Compression mode : Lossy
Delay relative to video : -1 s 501 ms
Stream size : 258 MiB (9%)
Language : English
Service kind : Complete Main
This delay can confuse some editing programs. If I cut segments out with ffmpeg the audio and video don't quite start in the same place. I would really like to have ffmpeg re-synchronize the files, but have not been able to do it. I've tried -vsync with various options (1, 2, vfr) -async with various options including -async 1 which the documentation seems to indicate will synchronize the beginning, -fflags +genpts+igndts in various combinations, -af aresample=async=1 , in every combination I can think of. In every single case, ffmpeg reads and writes with no reported errors: but the new file still has a "Delay relative to video" carried through to the new file. I've spend quite a lot of time on this, and all I have to show for it is severe aggravation.
The only thing I've found so far that comes close is to convert the file once, get the value of the delay, and then do this:
ffmpeg -err_detect ignore_err -hide_banner -loglevel info -stats -async 1 -itsoffset -1.501 -i "Story-09202022-0858.m2ts" -strict normal -map 0 -c:v copy -c:s mov_text -c:a aac -b:a 192k -ar 48000 Story-09202022-0858.mkv
This usually (but not always) re-encodes the audio in a way that does not show any significant delay between video and audio. However, it requires manually entering the values every time, and it must be exactly as I've shown it. Since -async is going to be "deprecated" (for no good reason I can see), I tried the so-called replacement of -af aresample=async=1 in this example and it did not work.
Can someone please tell me if there is a way to get ffmpeg to look at the information in a file that says what the delay is and then "fix" it? It seems very odd to me that there isn't a way to fix this synchronization between video and audio when the value of the off is is already known and available within the file.
If not, is there at least a way to obtain the value of the offset so I can write a command procedure (I normally use Windows for this, and have everything in BAT files) that will automate the procedure?
As I've said, I've searched through many forums, and all of the examples I've found have to do with audio and video being different tempos, or different durations, or similar problems. I've never seen an example of fixing the initial offset other than with -itsoffset.
If it matters, the ultimate output will be AVC (MP4) video and AAC audio. Unfortunately, just copying the audio in AC3 isn't going to work as there are some systems (such as DLNA servers and Roku Media Player) that can't handle it properly.
Thanks.
To respond to the question about ffprobe: you can get the delay, but the best that will happen is that you can direct the output to a text file. Then what do you do with it?
I prefer MediaInfo, which in this case will do the same thing:
mediainfo --Inform=Audio;%Video_Delay% "InputFile.m2ts
-666
(No, I'm not being flippant, that's the real delay on that particular file.)
Something similar could be done with ffprobe, but finding the exact command to return just one value is a royal pain.
Regardless, what would you do with a text file that just has one line with
-666
in it. How would you turn it into something that could go into the command line in a batch file?
I still maintain that since this data is in the input file, there ought to be a reasonable way to get ffmpeg to read it and use it.
I've been researching some additional possible commands, including -copyts, -async 1, variations on ignpts and genpts, -start_at_zero, and various -vsync options, and I can't find anything that will tell ffmpeg to use the delay to synchronize the audio and video streams.