ffmpeg-python
ffmpeg-python copied to clipboard
How to cut (`trim`) video and audio with timestamps
Great work!
I'm confused as to how to solve this problem, but am sure that it is solvable with a little guidance. I'm trying to trim a clip that should be 600/25(fps) = 24s long.
(
input_video
.trim (start_frame=10000, end_frame=10600) # output len --> 600 frames long
.output ('out.mp4' )
.run()
)
However, the output gives me a file that is 10600 frames long, where the first 10000 frames don't play in some video players while they skip over in others. Nevertheless, what I wish for is a clip that is only 600 frames long.
Additionally, my output files do not have any audio. This isn't an issue though, but a solution would be a nice bonus.
Thanks!
I have the same issue with start=, end= arguments
I also have the same issue with start and end kwargs. As stated about end seems to be working, but start does not select the start of the video. I tried some of the earlier release, with no success.
Update: I tried this with ffmpeg directly, and it doesn't work either. Looks like this library isn't the issue. As a workaround you can use the "start+duration" method. Some people discussing here: https://stackoverflow.com/questions/18444194/cutting-the-videos-based-on-start-and-end-time-using-ffmpeg
I found a solution:
(
input_vid
.trim (start_frame = 10000, end_frame = 10600)
.setpts ('PTS-STARTPTS')
.output (f'output.mp4')
.run()
)
.setpts ('PTS-STARTPTS') basically resets the timestamp to 0 after a trim filter has been passed. This fixes the first issue I raised.
The above output, however, does not have any audio attached to the output. This is due to ffmpeg's behavior, as has been discussed in detail in #26 , #208 and shown in this example. Mysteriously the input.audio or input.video didn't work for me, but the following code can be used as a template to do the same:
vid = (
input_vid
.trim(start = 100, end = 160)
.setpts('PTS-STARTPTS')
)
aud = (
input_vid
.filter_('atrim', start = 100, end = 160)
.filter_('asetpts', 'PTS-STARTPTS')
)
joined = ffmpeg.concat(vid, aud, v=1, a=1)
output = ffmpeg.output(joined[0], joined[1], 'out.mp4')
output.run()
@rsomani95 's snippet gave me the error below.
TypeError: Expected string index (e.g. 'a'); got 0
In my case, adding .node after joined solved the problem.
def trim(input_path, output_path, start=30, end=60):
input_stream = ffmpeg.input(input_path)
vid = (
input_stream.video
.trim(start=start, end=end)
.setpts('PTS-STARTPTS')
)
aud = (
input_stream.audio
.filter_('atrim', start=start, end=end)
.filter_('asetpts', 'PTS-STARTPTS')
)
joined = ffmpeg.concat(vid, aud, v=1, a=1).node
output = ffmpeg.output(joined[0], joined[1], output_path)
output.run()
Did you need .node even if you weren't adding .audio and .video to input_stream ?
Mysteriously, adding .audio or .video for me gives me an error that I haven't bothered figuring out, so I use ~.audio~[a] and ~.video~[v] when needed.
Removing .node gave me TypeError, regardless of adding .audio and .video or not.
Experiments were done with ffmpeg-python==0.1.18, Python 3.6 in macOS Mohave and Ubuntu 16.04
it couldn't wok on Google colab I had found one cutting code , but it is too slow But in android vidtrim is superfast I need a superfast cutting code Python
@TanvirMobasshir see this https://github.com/kkroening/ffmpeg-python/issues/184#issuecomment-504390452