0

I am a newbie to ffmpeg but currently using it Powershell to cut video clips from an mp4 file. What I am looking to do is cut a segment from a video and create a new mp4 file with such. I run the following command, see following example for one clip created. Run this multiple times with different start times and duration's through out the source file:

-ss 00:02:42.9060000 -i "C:\Users\User\Desktop\MySourceVideo.mp4" -t 00:00:07.2800000 -c:v copy "C:\Users\User\Desktop\MyClip.mp4" -y -v quiet

Source file is mp4, with H264 video codec, AAC video codec.

While it creates the clips, I run it at different times in the source video creating multiple cut mp4 videos. When I look to play the newly created mp4 files, for some clips I find some inconsistencies, such as:

  • Playing the file for first few seconds just has black scream
  • Playing the file for first few seconds has video moving very fast and then normal again

Some clips are perfect, others have the above issues. I would appreciate if my command could be checked in case I am missing a parameter or any further insight could be given?

szatmary
  • 29,969
  • 8
  • 44
  • 57
amateur
  • 43,371
  • 65
  • 192
  • 320
  • Could you please remove the Powershell tag as this is not related to any line of Powershell code? Thanks in advance. – Olaf Mar 31 '20 at 00:09
  • 1
    First, Don't use quiet. Maybe the log will tel you what's wrong. Second, you will probably need to transcode. `-codec copy` can only cut on key frames. – szatmary Mar 31 '20 at 01:37

1 Answers1

1

As mentioned in the comment section. You are trying to trim the video without encoding it. You are calling -c:v copy, this means that you want to copy the video stream - The problem with this is that it will seek to the previous key frame, that is why you are seeing the black frames at the start.

The other option is to figure out where the keyframes are and passing the time of the keyframe closest to the time that you want to trim.

I would suggest removing -c:v copy.


Edit:

You can use ffprobe to get the key/I frame closest to a given time, as shown below:

The given time is 2:30min - 150 seconds.

ffprobe -select_streams v -show_frames -show_entries frame=pkt_pts_time,pict_type -v quiet in.mp4 | awk -F= ' /pict_type=/ { if (index($2, "I")) { i=1; } else { i=0; } } /pkt_pts_time/ { if (i && ($2 >= 150)) print $2; } ' | head -n 1

Credit to this answer.


Or as mentioned in the comment section below (faster than above) Credit to this answer:

ffprobe -loglevel error -select_streams v:0 -show_entries packet=pts_time,flags -of csv=print_section=0 input.mp4 | awk -F',' '/K/ {print $1}
HB.
  • 4,116
  • 4
  • 29
  • 53
  • Thanks for this information - going to relook at the recoding. Any way to find where the keyframes is and using the timeframe closet to such? – amateur Mar 31 '20 at 08:26
  • Thanks very much @HB for this. I am working my way through it. Can you explain how I might pass the time to this and get a return value? I noted $1 and $2 in the syntax but not sure what they mean. Thanks again. – amateur Mar 31 '20 at 12:07
  • 2
    A much faster method: [Checking keyframe interval?](https://stackoverflow.com/a/18088156/) – llogan Mar 31 '20 at 17:46
  • @IIogan how do i use this to find the closest keyframe to my start time and use this as the new start time to cut it on? – amateur Mar 31 '20 at 18:00
  • @amateur Lazy method is to simply run the command and the look at the output and find whatever number is closest, or adapt the `awk` command from the slower method. – llogan Mar 31 '20 at 18:12
  • Thanks for everyones help – amateur Apr 01 '20 at 16:48