I want to compose 2 videos into 1 video by putting side by side.
I also hope to set start/stop time for each video.
Final video should be H264/AAC codec and mp4 format.
I attached sample videos.
https://www.dropbox.com/s/e5eouyrrqsy44ts/1.webm?dl=0
https://www.dropbox.com/s/u0zqie0icxamt3q/2.webm?dl=0
I used the following ffmpeg command.
ffmpeg -i 1.webm -i 2.webm -filter_complex "[0:v][1:v]hstack" output.mp4
When I run this command on Terminal of Mac OS X 10.11, It gave me the following error.
Input 1 height 480 does not match input 0 height.
The video are from smartphone, so its orientation is not correct.
Please help me to make composed video with FFmpeg.
For this set of videos, you need
ffmpeg -i 1.webm -i 2.webm -filter_complex "[0:v]scale=480:640,setsar=1[l];[1:v]scale=480:640,setsar=1[r];[l][r]hstack;[0][1]amix" -vsync 0 output.mp4
The writing application hasn't written the stream attributes correctly. The videos should be tagged as 480x640. It's not about a missing rotation tag, as the frame context changes.
Related
Before posting I have searched and found similar questions on stackoverflow (I list some below) - none have helped me towards a solution, hence this post. The duration that each image is shown within the movie file differs from many posts that I have seen thus far.
A camera captures 1 image every 30 seconds. I need stream them, preferably via HLS, thus I wrap 2 images in an MP4. I then convert MP4 to mpegts. Each MP4 and TS file play fine individually (each contain two images, each image transitions after 30seconds, each movie file is 1minute long).
When I reference the two TS files in an M3U8 playlist, only the first TS file gets played. Can anyone advise why it stops and how I can get it to play all the TS files that I expect to create, not just the first TS file? Besides my ffmpeg commands, I also include my VLC log file (though I expect to stream to Firefox/Chrome clients). I am using ffmpeg 4.2.2-static installed on an AWS EC2 with AMI2 Linux.
I have four jpgs named image11.jpg, image12.jpg, image21.jpg, image22.jpg - The images look near identical as only the timestamp in top left changes.
The following command creates 1.mp4, using image11.jpg and image12.jpg, each image displayed for 30 seconds, total duration of the mp4 is 1 minute. It plays like expected.
ffmpeg -y -framerate 1/30 -f image2 -i image1%1d.jpg -c:v libx264 -vf "fps=1,format=yuvj420p" 1.mp4
I then convert 1.mp4 to an mpegts file, creating 1.ts. It plays like expected.
ffmpeg -y -i 1.mp4 -c:v libx264 -vbsf h264_mp4toannexb -flags -global_header -f mpegts 1.ts
I repeat the above steps except specific to image21.jpg and image22.jpg, creating 2.mp4 and 2.ts
ffmpeg -y -framerate 1/30 -f image2 -i image1%1d.jpg -c:v libx264 -vf "fps=1,format=yuvj420p" 2.mp4
ffmpeg -y -i 1.mp4 -c:v libx264 -vbsf h264_mp4toannexb -flags -global_header -f mpegts 2.ts
Thus now I have 1.mp4, 1.ts, 2.mp4, 2.ts and all four play individually just fine.
Using ffprobe I can confirm their duration is 60seconds, for example:
ffprobe -i 1.ts -v quiet -show_entries format=duration -hide_banner -print_format json
My m3u8 playlist follows:
#EXTM3U
#EXT-X-VERSION:4
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-TARGETDURATION:60.000
#EXTINF:60.0000,
1.ts
#EXTINF:60.000,
2.ts
#EXT-X-ENDLIST
Can anyone advise where I am going wrong?
VLC Error Log (though I expect to play via web browser)
I have researched the process using these (and other pages) as a guide:
How to create a video from images with ffmpeg
convert from jpg to mp4 by ffmpeg
ffmpeg examples page
FFMPEG An Intermediate Guide/image sequence
How to use FFmpeg to convert images to video
Take a look at the start_pts/start_time in the ffprobe -show_streams output, my guess is that they all start at zero/near-zero which will cause playback to fail after your first segment.
You can still produce them independently but you will want to use something like -output_ts_offset to correctly set the timestamps for subsequent segments.
The following solution works well for me. I have tested it uninterrupted for more than two hours and believe it ticks all my boxes. (Edited because I forgot the all important -re tag)
ffmpeg will loop continuously, reading test.jpg and stream it to my RTMP server. When my camera posts an image every 30seconds, I copy the new image on top of the existing test.jpg which in effect changes what is streamed out.
Note the command below is all one line, I have put new lines in to assist reading and The order of the parameters are important - the loop and fflags genpts for example must appear before the -i parameter
ffmpeg
-re
-loop 1
-fflags +genpts
-framerate 1/30
-i test.jpg
-c:v libx264
-vf fps=25
-pix_fmt yuvj420p
-crf 30
-f fifo -attempt_recovery 1 -recovery_wait_time 1
-f flv rtmp://localhost:5555/video/test
Some arguments explained:
-re implies play in real time
loop 1 (1 turns the loop on, 0 off)
-fflags +genpts is something I only half understand. PTS I believe is the start/end time of the segment and without this flag, the PTS is reset to zero with every new image. Using this arguement means I avoid EXT-X-DISCONTINUITY when a new image is served.
-framerate 1/30 means one frame for 30seconds
-i test.jpg is my image 'placeholder'. As new images are received via a separate script, it overwrites this image. When combined with loop it means the ffmpeg output will reference the new image.
-c:v libx264 is for H264 video output formating
-vf fps=25 Removing this, or using a different value resulted in my output stream not being 30seconds.
-pix_fmt yuvj420p (sometimes I have seen yuv420p referenced but this did not work on my environment). I believe there are different jpg colour palettes and this switch ensures I can process a wider choice.
-crf 30 implies highest quality image, lowest compression (important for my client)
-f fifo -attempt_recovery 1 -recovery_wait_time 1 -f flv rtmp://localhost:5555/video/test is part of the magic to go with loop. I believe it keeps the connection open with my stream server, reduces the risk of DISCONTINUITY in the play list.
I hope this helps someone going forward.
The following links helped nudge me forward and I share as it might help others to improve upon my solution
Creating a video from a single image for a specific duration in ffmpeg
How can I loop one frame with ffmpeg? All the other frames should point to the first with no changes, maybe like a recusion
Display images on video at specific framerate with loop using FFmpeg
Loop image ffmpeg HLS
https://trac.ffmpeg.org/wiki/Slideshow
https://superuser.com/questions/1699893/generate-ts-stream-from-image-file
https://ffmpeg.org/ffmpeg-formats.html#Examples-3
https://trac.ffmpeg.org/wiki/StreamingGuide
i try to concat multiple videos to one video and add an background music to it.
for some reason the background music is perfectly added to the output video but the audio of each part of the output is speed up to a chipmunk version of the video itself. this results in an output video of 7 minutes with about 5 minutes of silence since everything is so fast that all the audio finishes after about 2 minutes.
my command is:
ffmpeg -safe 0 -i videolist.ffconcat -i bg_loop.mp3 -y -filter_complex "[1:0]volume=0.3[a1];[0:a][a1]amix=inputs=2" -vcodec libx264 -r 25 -filter:v scale=w=1920:h=1080 -map 0:v:0 output.mp4
i tried to remove the background music (since i wasn't able to loop it through the video i thought maybe that's the issue) and still.. all the audio of the video clips is still speed up resulting in chaotic audio at the beginning and silence at the end.
my video list looks like this:
ffconcat version 1.0
file intro.mp4
file clip-x.mp4
file clip-y.mp4
file clip-x.mp4
file clip-y.mp4
[... and so on]
i hope somebody can tell me what i'm doing wrong here (and maybe how to adjust my command to loop the background music through all the clips)
i googled a bit and found the adjustment of my command to add amix=inputs=2:duration=first but that doesn't do the trick and if i add duration=shortest or duration=longest nothing changes the output audio
The concat demuxer requires that all streams in inputs have the same properties. For audio, that includes codec, sampling rate, channel layout, sample format..
If audio of some inputs is sounding funny after concat, that usually indicates a sampling rate mismatch. Run ffprobe -show_streams -select_streams a -v 0 "input-file" on each input to check. For those which are different, you can re-encode only the audio by adding -ar X where X is the most common sampling rate found among your inputs e.g. -ar 44100. Other parameters will depend on format details. Keep video by using -c:v copy.
I have tried to speed up a video file (with the audio stream) 8 times with ffmpeg using the script below. All works well that from a 50 hour video I get a 7-hour video with the audio sped up also, yet in the resulting file the audio lasts for just over 2 hours and silences after that, i.e. there video without audio.
ffmpeg -i video.mp4 -filter_complex "[0:v]setpts=0.5*PTS,setpts=0.5*PTS,setpts=0.5*PTS[v];[0:a]atempo=2.0,atempo=2.0,atempo=2.0[a]" -map "[v]" -map "[a]" video_x8.mp4
EDIT:
video.mp4 file
video_x8.mp4 file (naming is different for the clear picture)
EDIT 1.
Here are the full 100MB logs. https://gofile.io/?c=L0Au2e
EDIT 2: Thank you Gyan. But could you please help me write it in 1 command so that it works in 1 go?
As far as I can tell, the atempo (whether due to the chaining or otherwise), is not updating timestamps correctly, so the remedy is to insert asetpts afterwards.
ffmpeg -i video.mp4 -vf "setpts=0.125*PTS" -af "atempo=8.0,asetpts=N/SR/TB" video_x8.mp4
I want to compose 2 videos into 1 video by putting side by side.
I also hope to set start/stop time for each video.
Final video should be H264/AAC codec and mp4 format.
I attached sample videos.
https://www.dropbox.com/s/e5eouyrrqsy44ts/1.webm?dl=0
https://www.dropbox.com/s/u0zqie0icxamt3q/2.webm?dl=0
I used the following ffmpeg command.
ffmpeg -i 1.webm -i 2.webm -filter_complex "[0:v][1:v]hstack" output.mp4
When I run this command on Terminal of Mac OS X 10.11, It gave me the following error.
Input 1 height 480 does not match input 0 height.
The video are from smartphone, so its orientation is not correct.
Please help me to make composed video with FFmpeg.
For this set of videos, you need
ffmpeg -i 1.webm -i 2.webm -filter_complex "[0:v]scale=480:640,setsar=1[l];[1:v]scale=480:640,setsar=1[r];[l][r]hstack;[0][1]amix" -vsync 0 output.mp4
The writing application hasn't written the stream attributes correctly. The videos should be tagged as 480x640. It's not about a missing rotation tag, as the frame context changes.
trying to get my head around ffmpeg to create a slideshow where each image is displayed for ~5 seconds with some audio. created a bat file to run the following so far:
ffmpeg -f image2 -i image-%%03d.jpg -i music.mp3 output.mpg
It gets the images and displayes them all very fast in the first second of the video, it then plays out the rest of the audio while showing the last image.
I want to make the images stay up longer (about 5 seconds), and stop the video after the last frame (not playing the rest of the song), are either of these things possible? i could hack the frame rate thing i guess by having hundreds of the same image in order to keep it up longer, but this is far from ideal!
Thanks
The default encoder for mpg output, mpeg1video, is strict about the allowed frame rates, so an input and an output -r are required:
ffmpeg -r 1/5 -i image-%03d.jpg -i music.mp3 -r 25 -qscale:v 2 -shortest -codec:a copy output.mpg
The input images will have a frame rate of 1 frame every 5 seconds and the output will duplicate frames to reach 25 frames per second.
-f image2 is generally not required.
-qscale:v can control output quality. A sane range is 2-5.
-shortest will make the output duration the same as the shortest input duration.
-codec:a copy copy your MP3 audio instead of re-encoding.
MPEG-1 video has more modern alternatives. See the FFmpeg and x264 Encoding Guide for more info.
Also see:
* FFmpeg FAQ: How do I encode single pictures into movies?
* FFmpeg Wiki: Create a video slideshow from images
You could use the filter fps instead of output framerate
ffmpeg -r 1/5 -i img%03d.png -i musicfile -c:v libx264 -vf fps=25 -pix_fmt yuv420p out.mp4
This however skips the last image for me strangely.