Re-encoding vlc-created mpeg2 .ts file results in 20 second file; AKA: multi-stream file with hidden streams
Asked Answered
D

2

1

I was recording something with vlc off v4l2 (in case that makes a difference), and I just selected the first format that worked, being mpeg2 using TS container. File resulted in .ts extension, as automatically selected by vlc. When I then tried to put the video file in my video editor, it said the video was 19,884 hours long, when it should be about 6 minutes (it is ~80mb in size). When I try to play it in xine, it correctly shows the duration (vlc doesn't), and when I use ffprobe:

[mpegts @ 0x9b2c0a0] max_analyze_duration 5000000 reached at 5000000
Input #0, mpegts, from 'loopbacktestcap.ts':   Duration: N/A, start:
17978.139456, bitrate: N/A   Program 1 
     Stream #0:0[0x44](): Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 104857 kb/s, 30 fps, 30
tbr, 90k tbn, 60 tbc
     Stream #0:1[0x46](): Video: mpeg2video ([2][0][0][0] / 0x0002), 90k tbn

Notice especially this line:

   Duration: N/A, start: 17978.139456, bitrate: N/A   Program 1 

I looked it up and it seems the lack of duration has to do with the container. But I have tried a few things to reencode (I tried -vcodec copy, mpeg2, libx264...) and all I can get is 20 second files of 1.1mb - 1.8mb.

So how can I reencode this file so the duration appears, and I get the full 6 minutes, instead of just the first 20 seconds?

Doughnut answered 12/11, 2016 at 20:0 Comment(9)
Downvoter, care to comment why?Doughnut
You should show the entire console output. Based on the incomplete readout pasted, it looks like your TS has multiple video streams in it. Unless you expressly map them, ffmpeg will pick one by default. Also, TS are transport streams. They don't have a global index, so some apps may surmise duration by looking at timestamps. And your file has a non-zero start time. Show the entire console output.Loquat
Hi @Mulvya, that is the entire output, the only thing missing is just ffmpeg version info, with config flags and lib versions. Is that what you mean that I should include too?Doughnut
I have since tried some other re-encoding tests, and nothing seems to work, even streaming it from one vlc to another and capturing from there does not work. Though simply playing it seems to play the whole thing through no problem.Doughnut
Try ffmpeg -fflags +genpts -i in.ts -map 0:v:0 v0.mp4 and ffmpeg -fflags +genpts -i in.ts -map 0:v:1 v1.mp4 and see if either of them is good.Loquat
First one has same problem, 20s vid generated, second one gives me an error: "[buffer @ 0x837c000] Invalid pixel format '-1' Error opening filters! "Doughnut
Ok, run ffmpeg -i in.ts -map 0:v:0 -c copy -f dvd v0.mpg and ffmpeg -i in.ts -map 0:v:1 -c copy -f dvd v1.mpg and see which is the larger file.Loquat
First one give a lot of buffer underflow warnings, but produces a 19 second file (now 4.6mb). Second command produces 0 byte file and this error: "Could not write header for output file #0 (incorrect codec parameters ?)"Doughnut
Ok I solved it. Check my answer to see how. Thanks for the help.Doughnut
D
2

First milestone was reached when I found this link: Map - ffmpeg -- Example #8 which led me to try:

ffmpeg -probesize 90M -analyzeduration 90M -i my_mpeg2_file.ts

Yielding the following:

[mpegts @ 0x9980f40] max_analyze_duration 90000000 reached at 90000000
Input #0, mpegts, from 'loopbacktestcap.ts':
  Duration: 00:16:00.96, start: 17978.139456, bitrate: 695 kb/s
  Program 1 
    Stream #0:0[0x44](): Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 104857 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #0:1[0x45](): Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 104857 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #0:2[0x46](): Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p, 640x480 [SAR 1:1 DAR 4:3], 104857 kb/s, 30 fps, 30 tbr, 90k tbn, 60 tbc

Notice that it now gives me the correct duration as well as an extra stream and more info on the second one (which is technically the third one). So then I ran:

ffmpeg -probesize 90M -analyzeduration 90M -i my_mpeg2_file.ts  -map 0 -c copy map0.mp4

and that now produced a 79451050 byte file map0.mp4, where my_mpeg2_file.ts is 83499636. I try to play this in vlc, and it shows the duration as 9:12, but if I jog the play position, two more vlc windows are opened and vlc begins to act strange; the video display area is hung, though the playback position indicator continues to progress. This might be just a buggy vlc, but I am stuck at this point. Let me know if anyone sees anything I am missing here.

xine however cannot play back the new file (where it plays the original and shows that it is 6 minutes long -- actually, the duration counter goes a little nutty as I play the file and changes constantly, so I don't know).

So, next command I tried was:

ffmpeg -probesize 90M -analyzeduration 90M -i my_mpeg2_file.ts  -map 0 -c libx264 map0x264.mp4

Trying to play the resulting file (43652975 bytes, for the curious) led to the same strange behavior in vlc, where now I can see that it is opening a new window for each stream, and playing the stream when it is its "turn" in its respective window, freezing the other display areas of the other windows. Trying to close them stops playback for all and closes the two extra windows. I am guessing keeping all 3 streams in the same file is nonsense.

SUCCESS!

Next attempt was:

ffmpeg -probesize 90M -analyzeduration 90M -i my_mpeg2_file.ts  -map 0:0 -c copy map0_0.ts
ffmpeg -probesize 90M -analyzeduration 90M -i my_mpeg2_file.ts  -map 0:1 -c copy map0_1.ts
ffmpeg -probesize 90M -analyzeduration 90M -i my_mpeg2_file.ts  -map 0:2 -c copy map0_2.ts

which resulted in files of size:

 4912 map0_0.ts
 5372 map0_1.ts
74728 map0_2.ts

map0_0.ts is 20 seconds long, map0_1.ts is a still image 1:12 long, and map0_2.ts is 9:12. Exactly what I wanted! And my video editor accepts them no problem. SOLVED!

Doughnut answered 23/11, 2016 at 11:5 Comment(0)
C
0

I had a similar challenge of supporting transport stream (ts) video files in our video processing infrastructure. I used ffmpeg to convert ts into mp4 files with two-pass encoding.

The command(s) in its full length:

Pass 1:

ffmpeg -i camera.ts -filter:v scale=-1:480,setsar=1/1 -pix_fmt yuv420p -threads 0 -r 25/1 -force_fps -c:v libx264 -profile:v baseline -preset slow -x264opts level=3.0:ref=1 -b:v 1000k -maxrate 1000k -bufsize 2000k -s hd480 -c:a libfaac -ar 16000 -ac 2 -ab 128000 -pass 1 -movflags faststart -y video.mp4

Pass 2:

ffmpeg -i camera.ts -filter:v scale=-1:480,setsar=1/1 -pix_fmt yuv420p -threads 0 -r 25/1 -force_fps -c:v libx264 -profile:v baseline -preset slow -x264opts level=3.0:ref=1 -b:v 1000k -maxrate 1000k -bufsize 2000k -s hd480 -c:a libfaac -ar 16000 -ac 2 -ab 128000 -pass 2 -movflags faststart -y video.mp4 >>& ffmpeg.log

I downscale the video to hd480 (852x480) reencoding the video stream with libx264 baseline level 3 with a relatively low bitrate as well as audio with libfaac and moving the moov atom to the beginning of the file for web compatibility (-movflags faststart)

See the FFMpeg documentation for all details on the flags.

Note that I just dug up this command which works for our setup: processing transport stream recordings from IP cameras. You would probably need to specifically adapt resolution and bitrates to your needs. Hope this points you in the right direction.

Corrianne answered 14/11, 2016 at 9:27 Comment(5)
Hi, thanks for the answer, the first command fails for me though: "[setsar @ 0x8edbc80] Invalid string '1/1' for aspect ratio. Error initializing filter 'setsar' with args '1/1'" removing the setsar argument then gave ma another error: "[mp4 muxer @ 0x83b0340] [Eval @ 0xbfcfd16c] Undefined constant or missing '(' in 'faststart' [mp4 muxer @ 0x83b0340] Unable to parse option value "faststart" [mp4 muxer @ 0x83b0340] Error setting option movflags to value faststart. Could not write header for output file #0 (incorrect codec parameters ?)"Doughnut
Focus on one parameter at first. Errors may be encapsulated. Try to get the aspect ratio right. Play around with setsar. Try setsar=sar=1/1 or setsar=1 or setsar=1:1 see: ffmpeg.org/ffmpeg-all.html#setdar_002c-setsar for all infos on the parameter. Another approach would be to remove the complete chain of filter:v scale=-1:480,setsar=1/1 and only work with -pix_fmt yuv420p - it could also apply to your setup that you don't want to change the resolution - however that I don't know.Corrianne
Ok, I tried this command: ffmpeg -i loopbacktestcap.ts -filter:v scale=-1:480,setsar=1 -pix_fmt yuv420p -threads 0 -r 25/1 -force_fps -c:v libx264 -profile:v baseline -preset slow -x264opts level=3.0:ref=1 -b:v 1000k -maxrate 1000k -bufsize 2000k -s hd480 -c:a libfaac -ar 16000 -ac 2 -ab 128000 -pass 1 overflownosetsar.mp4 but the file generated is still just 20 seconds longDoughnut
To clarify, I changed it to "setsar=1" and removed the "-movflags faststart -y"Doughnut
Thanks for the answer, I have now solved it. Check my answer to see how.Doughnut

© 2022 - 2024 — McMap. All rights reserved.