I use https://github.com/Zulko/moviepy library for merge two videos with python. It merged successfully but sound of videos is not exists in merged.mp4.
The python code :
clip1 = VideoFileClip("2.mp4",audio=True)
clip2 = VideoFileClip("1.mp4",audio=True)
final_clip = concatenate_videoclips([clip1,clip2],method="compose")
final_clip.write_videofile("merged.mp4")
I also tried with ffmpeg
ffmpeg -i 'concat:1.mp4|2.mp4' -codec copy merged.mp4
ffmpeg couldn't merge videos. It create merged.mp4 which has only 1.mp4
How can I merge two videos with python or another way?
ffmpeg offcial
Instructions
Create a file mylist.txt with all the files you want to have concatenated in the following form (lines starting with a # are ignored):
file 'path/to/file1.wav'
file 'path/to/file2.wav'
file 'path/to/file3.wav'
Note that these can be either relative or absolute paths. Then you can stream copy or re-encode your files:
ffmpeg -f concat -safe 0 -i mylist.txt -c copy mergedfile.mp4
The -safe 0 above is not required if the paths are relative.
It works for all kinds of video formats mp4, wav ...
Related
i want to select videos from file1.txt which contains
file 'video1.mp4'
file 'video2.mp4'
file 'video3.mp4'
using ffmpeg command i store them in file1.txt and concatenate it:
command= ffmpeg -f concat -i < ( for f in *.mp4; do echo "file '$(pwd)/$f'"; done ) outputfile.mp4
how to apply start and end to this so that i can select videos starting from video1.mp4 to video2.mp4 to be concatenated using python.
I am trying to extract the frames when the scene changes in an .mp4 video.
The package that I am using is FFMPEG.
FFMPEG predominantly works on the CLI and I am trying to integrate it with Python3.x
The command I am using in the CLI is:
ffmpeg -i {0} -vf "select=gt(scene\,0.5), scale=640:360" -vsync vfr frame%d.png
The output comes out just fine with the CLI execution.
But I want to use same command in a Python script, how do I do that and what should be the code?
Being an amateur in the field, currently grappling with this!
You could execute that command from Python via subprocess module, of course, but it would better to use library like https://github.com/kkroening/ffmpeg-python
I would recommend PyAV. it's a proper wrapper around ffmpeg's libraries.
the other mentioned packages use the "subprocess" approach, which is limited and inefficient. these libraries may be more convenient than plain ffmpeg APIs.
Thanks for the help!
This is the snippet of code I'm currently using and it gives the results as I require.
I have added a functionality for timestamp generation of the frames in addition to the frame formation using scene change detection
===========================================================================
> # FFMPEG Package call through script
> # need to change the location in the cmd post -vsync vfr to the location where the frames are to be stored
> # the location should be same as where the videos are located
============================================================================
inputf = []
for filename in os.listdir(path):
file= filename.split('.')[0] # Splits the file at the extension and stores it without .mp4 extension
input_file = path + filename
inputf.append(input_file) # Creates a list of all the files read
for x in range (0, len(inputf)):
cmd = f'ffmpeg -i {inputf[x]} -filter_complex "select=gt(scene\,0.2), scale=640:360, metadata=print:file=time_{file}.txt" -vsync vfr {path where the videos are located}\\{file}_frame%d.jpg'
os.system(cmd)
x=x+1
print("Done") # Takes time will loop over all the videos
I am trying to split clips into short intervals (that I am reading in from a csv) using ffmpeg. The commands that I'm using look like this:
ffmpeg -i filename.mp4 -ss 00:00:00.030000 -to 00:00:02.030000
-pix_fmt yuv420p -c copy new_filename.mp4
This successfully splits the parent mp4 into many smaller mp4s, but the smaller files lose some or all of their video. Most of them end up being just audio. Some have video - but only for about half of the clip (the rest is black). The audio is always there. Any ideas why this might be happening?
A couple notes: I'm using ffmpeg 3.0.2. Also, I am creating this command as a Python list and running it with the following call
subprocess.run(cmd, stderr=subprocess.STDOUT)
This was answered by comments from Mulvya and szatmary. Posting those as an answer to close out question.
"The OP is streamcopying. To the OP, if you change -c copy to -c:a
copy, it will work." –Mulvya
"-c copy will not work because there are no keyframes in that time
range. Your must reencode." –szatmary
The solution Mulvya suggested was to add a stream specifier. I did this, and got the result I was looking for. There's documentation here: https://ffmpeg.org/ffmpeg.html#Stream-specifiers-1
I am trying to detect if a video has any valid content or is just the standard broadcasting bars & tone. So far I've looked at this question: https://superuser.com/questions/1036449/detect-color-bars-ffmpeg/1036478#1036478
which generates bars & tone from the first frame and then compares that against the rest of the stream but in my case I need to run the ffmpeg command within a folder that only has one file that has already been found by my python script.
Is it possible to use ffmpeg's blend=difference to check that a short bars & tone clip is a subclip of one of my video files? I'm thinking of this in the same way you can check if a string is within a string, or is there a better way to check for bars that I'm not thinking of?
Thanks!
I found a way to get my script to do what I wanted with python and ffmpeg:
Info on how this ffmpeg command works:
https://unix.stackexchange.com/questions/101558/compare-video-and-image-percentage-of-differences
http://ffmpeg.org/ffmpeg-filters.html#Video-Filters
-------------------------------------------------------- BEGIN CODE -------------------------------------------------------
selection = "'gt(scene\,0.1)'" # The decimal here is the threshold for determining video quality (0 -> 1)
proc5 = Popen('C:/ffmpeg/bin/ffmpeg.exe -i "'+ src +'" -vf "select='+ selection +'" -vsync 0 -f image2 -y //fn101cdmzst01.foxneo.com/signiant/foxsports/soundmouse/FileManagerInfo/Thumbnails/thumbnails-%02d.jpg 2>&1', stdout=PIPE, shell=True) # This is the ffmpeg command. The specifics of how it works are explained below
res, err = proc5.communicate() # Read proc5's (the ffmpeg command) stdout to res and stderr to err
proc5.wait() # Wait for ffmpeg to finish processing the whole video file
res = str(res.decode('ascii')) # Decode the ascii output from stdout and convert to a string
print(res)
if r"Output file is empty" in res: # If the ascii output from stdout has the string "Output file is empty", remove it. Otherwise, perform name changes and file move for soundmouse
----------------------------------------------------------- END CODE -------------------------------------------------------
FFMPEG COMMAND: 'C:/ffmpeg/bin/ffmpeg.exe -i "'+ src +'" -vf "select='+ selection +'" -vsync 0 -f image2 -y //fn101cdmzst01.foxneo.com/signiant/foxsports/soundmouse/FileManagerInfo/Thumbnails/thumbnails-%02d.jpg 2>&1'
The actual ffmpeg command is highlighted according to the various operations it performs.
C:/ffmpeg/bin/ffmpeg.exe # make an absolute path call to ffmpeg.exe
-i "'+ src +'" # set the absolute path to the source file as the input
-vf "select='+ selection +'" # use a video filter to select frames with large change before and after (based on the decimal threshold that is set) and compare it with the following portion of the command
-vsync 0 -f image2 -y //fn101cdmzst01.foxneo.com/signiant/foxsports/soundmouse/FileManagerInfo/Thumbnails/thumbnails-%02d.jpg # compare the selected frame with the previous one stored in the Thumbnails folder and then overwrite the comparison thumbnail with the selected frame for the next comparison
2>&1' # redirect stderr to stdout so that we can read it with Python's proc5.communicate() function
I have 100 uncompressed mov (Video files) and i want to convert all mov to sgi image sequences.
i have a list of all mov file path.
how to convert .mov (video) to .sgi (image sequence) using python and FFmpeg.
you can use ffmpeg to convert the video to sgi images using this ffmpeg command
ffmpeg -i inputVideo outputFrames_%04d.sgi
-replace inputVideo your input file path and name
-replace outputFrames with output file path and name
-replace '4' in _%04d with the number of digits you want for sequential image file naming.
now one way to process your files from python is to launch ffmpeg as a subprocess and providing the command you want executed by ffmpeg:
import subprocess as sp
cmd='ffmpeg -i inputVideo outputFrames_%04d.sgi'
sp.call(cmd,shell=True)
remember to use double \ in your file path in the cmd command string (at least for me on windows).
If you want to loop over 100 movie files, write a loop that concatenates the command string with the appropriate input and output file names.