3

I have the following command:

ffmpeg -f f32le -ar 44100 -channels 2 -i pipe:0 -ss 3 -i input.mp4 -y -f mp4 -map 0:a -map 1:v -c:v copy -use_editlist 0 output.mp4

When copying the video stream instead of re-encoding it, I can't get any useful information out of ffprobe that tells me the seeked position of the video stream.

I tried gathering information on the complete stream:

ffprobe -of json -show_streams -show_format output.mp4

But start_time is 0 and the duration is unaffected. I also tried gathering information on the first frame of the video stream:

ffprobe -of json -select_streams v -show_frames output.mp4

Still no useful information.

However, when I re-encode the video stream (by removing -c:v copy from the command), I get the information I want. The video stream duration is modified by the -ss option. For example if the duration of the video is 5, then ffprobe would return a duration of 2 (5 minus 3), which lets me know the seeked position. If I also throw in a -copyts to the mix, then I can get the useful information by checking the first frame's info.

How can I get the seeked position without having to re-encode the video stream? Cheers!

Pavel Binar
  • 325
  • 2
  • 4
  • 11
Maxime Dupré
  • 79
  • 1
  • 1
  • 14
  • I don't really understand what you mean by "seeked position". Can you clarify what you need, and why you need this information? When you seek and copy, are you saying that the output is still 5 s long instead of 2? (It seems to me you're trying to solve another problem by “getting the seeked position”. What is that underlying problem?) – slhck May 27 '19 at 06:55
  • Are you trying to follow the progress of ffmpeg? There are many solutions for that. – harrymc May 27 '19 at 09:22
  • @ slhck What I mean by seeked position is the value of `-ss`. I need to get the `-ss` value of a video stream of an mp4 file for testing purposes. Indeed, when I seek and copy, the duration of the video stream is still 5 seconds instead of 3. But that doesn't matter if there's another attribute I can look at that will let me know what the seeked position. The information doesn't necessarily needs to be deduced from the duration attribute. – Maxime Dupré May 27 '19 at 12:49
  • Do you want the original timestamp of the first frame in the output? – Gyan May 28 '19 at 07:31
  • @Gyan What would be the original timestamp in my example? 0? 3? To answer your question, I am indifferent in regards to the original timestamp, as long as I can get the `-ss` info. – Maxime Dupré May 28 '19 at 13:59
  • Try seeking in the input instead of the output by specifying the -ss option BEFORE the -i option. Then, your output.mp4 would be 3 seconds instead of 5, and you can calculate the seeked position by subtracting the duration of output.mp4 from the duration of input.mp4 – ThatOneDude May 28 '19 at 23:23
  • Will you have access to the original file? – Gyan May 29 '19 at 10:48
  • @ssnobody I am seeking the (second) input... – Maxime Dupré May 29 '19 at 19:43
  • @Gyan Yes, I have access to the original file. – Maxime Dupré May 29 '19 at 19:44
  • But you aren't seeking the first, so you still end up with a 5 second file instead of a 3. Try seeing both inputs to the appropriate place. – ThatOneDude May 29 '19 at 21:50
  • @ssnobody I only want the video stream to start at 3 seconds, not the audio stream. – Maxime Dupré May 30 '19 at 15:49
  • Are you expecting 2 seconds of blank video but still have audio playing? My understanding is that if you don't use -ss or -t, for the first channel (audio), then you'll get a 5 second video. If you don't want to skip forward in the audio, use -t 3 to get the 3 second output and then calculate as above. – ThatOneDude May 30 '19 at 21:36
  • I'm expecting 3 seconds of audio without video, then onwards with the video and audio, yes. – Maxime Dupré Jun 02 '19 at 00:26

1 Answers1

3

If you've access to the original file and you've used

ffmpeg -f f32le -ar 44100 -channels 2 -i pipe:0 -ss X -i input.mp4 -y -f mp4 -map 0:a -map 1:v -c:v copy -use_editlist 0 output.mp4

then follow this method.

1) Get duration of source video stream

ffprobe source.mp4 -show_entries stream=duration -select_streams v -of compact=p=0 -v 0

Output e.g.

duration=229.033333

2) Get duration and first PTS of resulting video stream

ffprobe output.mp4 -show_entries packet=pts_time:stream=duration -select_streams v -read_intervals 0%+#1 -of compact=p=0 -v 0

Output e.g.

pts_time=0.066667
duration=220.700000

So, first frame in result is 229.033333 - 220.700000 = 8.333333s of the source stream.

However, this won't be the -ss value, since the -ss may not point to a keyframe.

3), So, get duration and PTS of first audio packet. ffmpeg will give it a prolonged duration to sync the audio with the specified -ss frame.

ffprobe output.mp4 -show_entries packet=pts_time,duration_time -select_streams a -read_intervals 0%+#1 -of compact=p=0 -v 0

Output e.g.

pts_time=0.000000|duration_time=2.733333

So, 8.333333s + 2.733333 - 0.000000 - 0.066667 = 11.000000s is the sought frame.

Gyan
  • 34,439
  • 6
  • 56
  • 98