Say I have a 30s video. I want to produce a 40s video that is just the first video but with an extra "freezed" frame (for say 10s) somewhere in the middle of it. (think of it as wanting to comment the video at a specific point)
I know I can do this easily with video editing software. However, I am looking for a command line tool that allows me to do this efficiently (I need to do this several times with variable points to freeze the video)
I am using Python
I thought of using ffmpeg, splitting the video into two, creating a third video composed of a given frame, and then concatenating the three videos.
But maybe there is a much simpler technique?
I found a way to do it
Let's say I have the original movie file: in.mp4
and I want to pause it for 10 seconds with the frame found at the 15s mark
#first extract the frame
ffmpeg -ss 00:00:15 -i in.mp4 -vframes 1 -q:v 2 -y static_frame.png
# Create the movie_aux1.mp4 of the first part of the original video
ffmpeg -t 00:00:15 -i in.mp4 movie_aux1.mp4
# Create the movie_aux2.mp4
ffmpeg -loop 1 -i static_frame.png -t 10 movie_aux2.mp4
# Create the movie_aux3.mp4
ffmpeg -ss 00:00:15 -i in.mp4 movie_aux3.mp4
# Create a list of the movies to concatenate. Dont forget to erase this file afterwards
echo "file 'movie_aux1.mp4'" >> mylist.txt
echo "file 'movie_aux2.mp4'" >> mylist.txt
echo "file 'movie_aux3.mp4'" >> mylist.txt
# Concatenate all three movies
ffmpeg -f concat -safe 0 -i mylist.txt out.mp4
Related
I am working with python in a jupyter notebook, and I am trying to use ffmpeg to specify the start and end images and convert several images from a folder into a single video. I have a folder, 'images', with the images inside labeled, 'image0', 'image1', 'image2', etc. I would like to specify the start and end images in my video. For example, I would like to be able to make the video using 'image100', to 'image200'. Right now, I have:
!/home/jovyan/ffmpeg-dir/ffmpeg -i /home/jovyan/images/image%d.bmp -frames:v 1000 /home/jovyan/output.mp4
This is making the video correctly, but I believe it is just taking the first 1000 images.
Thanks!
Use -start_number.
Use the -start_number option to declare a starting number for the sequence. This is useful if your sequence does not start with img001.jpg but is still in a numerical order.
(source: https://ffmpeg.org/faq.html#toc-How-do-I-encode-single-pictures-into-movies_003f)
For example, I would like to be able to make the video using 'image100', to 'image200'.
You need to combine -start_number 100 and -frames:v 101 (101 frames from image100.jpg to image200.jpg).
You can try this:
ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4
OR
ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 -c copy cut.mp4
The -t option specifies a duration, not an end time. The above command will encode 8s of video starting at 3s. To start at 3s and end at 8s use -t 5. If you are using a current version of ffmpeg you can also replace -t with -to in the above command to end at the specified time.
I have 2 separate webm files - video and audio part. Now I want to merge it. I use python and ffmpeg
input_video = ffmpeg.input(f'{title}-video.webm').output("out1.webm")
input_audio = ffmpeg.input(f'{title}-audio.webm').output("out2.webm")
ffmpeg.merge_outputs(input_video, input_audio).run()
Output file looks OK (it plays audio and video) but it takes time to merge it. I guess there's a needless conversion that I could avoid. Is it possible to do with the given API?
I googled a command
ffmpeg -i 12m.mp4 -i 6m.mp4 -c copy -map 1:v -map 0:a -shortest new.mp4
that should be run via command line, but I'd like to implement it by means of the API if it is possible.
So I am creating multiple video clips in Python using FFMPEG, I am then trying to concat these together. I create multiple videos named result1000, result1001 etc, then I create a transition effect I want to layer between these videos. The result1000, result1001... etc concat together perfectly fine, however inserting the transition effect between them causes every clip after the first transition to lose audio.
Creating the transiton
ffmpeg -loop 1 -y -i media/templates/bg.png -i media/swoosh_sound.mp3 -shortest -acodec copy -vcodec libx264rgb output/swoosh.mp4
Creating video clips
ffmpeg -loop1 -y -i image_files/image+str(1000+i)+.png -i audio_files/audio+str(1000+i)+.mp3 -shortest -acodec copy -vcodec libx264rgb output/result+str(1000+i)+.mp4
The ffmpeg_files.txt then looks something like this
file 'output/result1000.mp4'
file 'output/result1001.mp4'
file 'output/result1002.mp4'
file 'output/result1003.mp4'
file 'output/result1004.mp4'
file 'output/swoosh.mp4'
file 'output/result1005.mp4'
file 'output/result1006.mp4'
and the concat command im using is
ffmpeg -f concat -safe 0 -i ffmpeg_files.txt output/no_bg_out.mp4
In console on running the concat comment it will say
[mov,mp4,m4a,3gp,3g2,mj2 # 000001f289b44c40] Auto-inserting h264_mp4toannexb bitstream filter
for each resultXXXX clip, then as soon as it reaches a transition clip it starts spamming
[mp4 # 000001aa093ad100] Non-monotonous DTS in output stream 0:1; previous: 13619623, current: 8777816; changing to 13619624. This may result in incorrect timestamps in the output file.
I have read over the solutions mentioned Here but none of them seem to solve my issue. It should be noted that all video clips are created from .mp3 audio files and .png image files.
All attributes must match, but swoosh.mp4 varies from the rest with a different audio sample rate and channel layout. Re-encode the audio and try again:
ffmpeg -i swoosh.mp4 -c:v copy -c:a libmp3lame -ar 24000 -ac 1 -b:a 32k swoosh2.mp4
I have 4 movie files that I am trying to overlay and concatenate:
Intro file with an empty audio channel (generated using lavfi)
Main movie file(s) that need to be concatenated and trimmed
Watermark that needs to be overlaid on top of 2
An outro movie that also has an empty channel.
Here is the command I am using to do all this:
ffmpeg -i temp_intro.mp4 -f concat -i tempFile.txt -i scoreboard.mp4 -i temp_outro.mp4 \
-filter_complex "[1]trim=end=24:start=12[s0];[s0]setpts=PTS-STARTPTS[s1];[1]atrim=end=24:start=12[s2];[s2]asetpts=PTS-STARTPTS[s3];\
[s1][s3]concat=a=1:n=1:v=1[s4];\
[2]format=yuva444p[s5];[s5]colorchannelmixer=aa=0.5[s6];\
[s4][s6]overlay=eof_action=repeat:x=(main_w-overlay_w)/2:y=main_h-overlay_h-20[s7];\
[0][s7][3]concat=n=3[s8]" test.mp4
Despite how ugly it looks, it mostly works - except for the audio. The audio starts playing as soon as the intro clip starts. I cannot create an output file with the overlaid movie because I also need to add fade-out and fade-in effects for the intro and outro. I can only re-encode once since I will be doing this over multiple large files every night.
Please suggest how I might be able to fix the audio issue.
Solution is easy - just need to concatenate audio and video for the file explicitly in the second concat. Here is the command:
ffmpeg -i temp_intro.mp4 -f concat -i tempFile.txt -i scoreboard.mp4 -i temp_outro.mp4 \
-filter_complex "[1]trim=end=24:start=12[s0];[s0]setpts=PTS-STARTPTS[s1];[1]atrim=end=24:start=12[s2];[s2]asetpts=PTS-STARTPTS[s3]; \
[2]format=yuva444p[s4];[s4]colorchannelmixer=aa=0.5[s5]; \
[s1][s5]overlay=eof_action=repeat:x=(main_w-overlay_w)/2:y=main_h-overlay_h-20[s7]; \
[0:v:0][0:a:0] [s7][s3] [3:v:0][3:a:0]concat=n=3:v=1:a=1[s8]" -map [s8] test.mp4
I want to capture video from a webcam (saving to file), while occasionally getting the most recent still frame (from python code). Is there a way to do this on Linux?
What I've Tried:
# Capture Video:
ffmpeg -f v4l2 -framerate 30 -video_size 1024x576 -i /dev/video0 myvideo.mp4
...
# In another terminal, try to capture the latest still frame:
ffmpeg -sseof -3 -i myvideo.mp4 -update 1 -q:v 1 current_frame.jpg
But, I get varied responses from this last command, such as
Cannot use -sseof, duration of myvideo.mp4 not known
and
[matroska,webm # 0x55e1aae26900] Duplicate element
Last message repeated 2 times
Additional Notes/Constraints:
It must be possible to control the solution from python (e.g. calling ffmpeg via subprocess.Popen) to (a) start recording, (b) get frames at arbitrary points, (c) stop recording.
Frame timing doesn't have to be exact. A frame within the last couple seconds is fine.
Any container format is fine (mkv, mp4, etc.)
Other programs are fine, not just ffmpeg
You can have multiple outputs for FFmpeg. Combine your commands:
ffmpeg -f v4l2 -framerate 30 -video_size 1024x576 -i /dev/video0 myvideo.mp4 -r 1 -update 1 current_frame.jpg