Reputation: 141
I seem to be losing frames when I clip videos up with ffmpeg.
Here are the steps I take:
[Get the Frame number to cut on] -> [turn the frame number into hh:mm:ss.ms format] -> [Run ffmpeg process]
Here is the code:
import subprocess
def frames_to_timecode(frame,frameRate):
'''
Convert frame into a timecode HH:MM:SS.MS
frame = The frame to convert into a time code
frameRate = the frame rate of the video
'''
#convert frames into seconds
seconds = frame / frameRate
#generate the time code
timeCode = '{h:02d}:{m:02d}:{s:02f}'.format(
h=int(seconds/3600),
m=int(seconds/60%60),
s=seconds%60)
return timeCode
frameRate = 24.0
inputVideo = r"C:\Users\aquamen\Videos\vlc-record-2018-10-23-17h11m11s-SEQ-0200_animatic_v4_20180827_short.mp4"
outputVideo = r"C:\Users\aquamen\Videos\ffmpeg_test_clip001.mp4"
ffmpeg = r"C:\ffmpeg\ffmpeg-20181028-e95987f-win64-static\bin\ffmpeg.exe"
endFrame = frames_to_timecode(29,frameRate)
startFrame = frames_to_timecode(10,frameRate)
subprocess.call([ffmpeg,'-i',inputVideo,'-ss',startFrame,'-to',endFrame,outputVideo])
Here is a image of the original video and the clipped video with the time codes showing a frame was lost in process. The time code should show 00:01:18:10 instead its 00:01:18:11.
Upvotes: 0
Views: 1177
Reputation: 141
So a friend of mine figured this out. So if you divide the frame by the fps (Frame/fps) you get the point of when that frame needs to be cut with the -ss but the problem is by default python rounds the 12 decimal place. So you need to NOT round the number and give ffmpeg only up to 3 decimal places.
So here is my revised code for any one running into this problem. If you want to cut a video on the Frame number use this:
import subprocess
def frame_to_seconds(frame,frameRate):
'''
This will turn the frame into seconds.miliseconds
so you can cut on frames in ffmpeg
frame = The frame to convert into seconds
frameRate = the frame rate of the video
'''
frameRate = float(frameRate)
seconds = frame / frameRate
result = str(seconds - seconds % 0.001)
return result
inputVideo = "yourVideo.mp4"
outputVideo = "clipedVideo.mp4"
ffmpeg = r"C:\ffmpeg\bin\ffmpeg.exe"
frameRate = 24
subprocess.call([ffmpeg,
'-i',inputVideo,
'-ss',frame_to_seconds(10,frameRate),
'-to',frame_to_seconds(20,frameRate),
outputVideo])
Upvotes: 4