how do I fix this ffmpeg code to convert multiple folders to multiple mp4 - python

i have this code and I want to iterate through each folder in this directory, collect the files in each directory, and output it as 1 video per folder.
I keep getting the following error
"Could find no file with path './inputFrames/08KKF_Right/08KKF_Right.%04d.png' and index in the range 0-4
./inputFrames/08KKF_Right/08KKF_Right.%04d.png: No such file or directory
ffmpeg -f image2 -r 30 -i ./inputFrames/08KKF_Right/08KKF_Right.%04d.png -vcodec mpeg4 -y ./videos/08KKF_Right.mp4"
This is my code:
import os
dirs = os.listdir('./inputFrames/')
for x in dirs:
frames = os.listdir('./inputFrames/' + x)
#print(frames)
for y in frames:
yFrameO = y[:-8]
yFrame = "./inputFrames/"+ yFrameO[:-1] + "/"+ yFrameO + "%04d.png"
inputOS = "ffmpeg -f image2 -r 30 -i " + yFrame + " -vcodec mpeg4 -y ./videos/" + yFrameO[:-1]+".mp4"
#print(inputOS)
print("\n")
os.system(inputOS)
This is the code that works for a single folder that I'm trying to make work for multiple folders:
os.system("ffmpeg -f image2 -r 30 -i ./08KKF_Right/08KKF_Right.%04d.png -vcodec mpeg4 -y ./videos/08KKF_Right.mp4")
It tries to run the command on each image in each sub-Folder, so I get over 900 function calls and each of them erroring with the
how do I make it work for each folder? all the videos can be output to a single folder called "./videos"
thank you! :)

Related

Is there a way to stop ffmpeg from combining mp4s at max mp4 size?

I am merging 64 gigs of mp4s together, though ffmpeg will go past the file size limit and corrupt it. Is there a way to stop ffmpeg at a 100 hour mark and create another file, resume, then repeat until finished?
This is my python code, with the ffmpeg code I used to generate the mp4. It works fine with less files/
from moviepy.editor import *
import os
from natsort import natsorted
L = []
total = 0
for root, dirs, files in os.walk("F:\door"):
#files.sort()
files = natsorted(files)
with open("list.txt", "a") as filer:
for file in files:
if os.path.splitext(file)[1] == '.mp4':
filePath = os.path.join(root, file)
head, tail = os.path.split(filePath)
filePath = "file '" + str(tail)+"'\n"
print(filePath)
filer.write(filePath)
#run in cmd: ffmpeg -f concat -i list.txt -c copy output.mp4

How to cut videos automatically using Python with FFmpeg?

I'm trying to cut videos automatically using Python with FFmpeg so I don't have to type out the command everytime I want a new video cut. I'm not really sure what I'm doing wrong though, here's the code:
import os
path = r'C:/Users/user/Desktop/folder'
for filename in os.listdir(path):
if (filename.endswith(".mp4")):
command = "ffmpeg - i" + filename + "-c copy -map 0 -segment_time 00:00:06 -f segment -reset_timestamps 1 output%03d.mp4"
os.system(command)
else:
continue
Typos
First of all, there's a typo in the syntax, as you wrote - i while the correct syntax is -i.
The syntax " + filename + " is correct, however there must be a space before and after
command = "ffmpeg -i " + filename + " -c copy -map 0 -segment_time 00:00:06 -f segment -reset_timestamps 1 output%03d.mp4"
otherwise, you would get an error like
Unrecognized option 'iC:\Users\user\Desktop\folder\filename.mp4-c'.
Error splitting the argument list: Option not found
Solution
I assumed every other argument is correct, for me it didn't work at first, I just had to add
-fflags +discardcorrupt
but maybe it's just my file.
Here's the correct code, however I recommend to you to read this.
Note: I used os.path.join() to save the output file in that same directory because my python file was in another one.
import os
path = r'C:\Users\user\Desktop\folder'
for filename in os.listdir(path):
if filename.endswith(".mp4"):
command = "ffmpeg -fflags +discardcorrupt -i " + os.path.join(path, filename) + " -c copy -map 0 -segment_time 00:00:03 -f segment -reset_timestamps 1 " + os.path.join(path, "output%03d.mp4")
os.system(command)
else:
continue
You can cut a video file with ffmpeg.
ffmpeg -i 1.mp4 -vcodec copy -acodec copy -ss 00:03:20 -t 00:10:24 out.mpt
-ss : start_time
-to : end_time
-t : duration_time

Merge Audio and Video using ffmpeg - Python Lib [duplicate]

I'm trying to combine a video(with no sound) and its separate audio file
I've tried ffmpeg ffmpeg -i video.mp4 -i audio.mp4 -c copy output.mp4
and it works fine.
i'm trying to achieve the same output from ffmpeg-python but with no luck. Any help on how to do this?
I had the same problem.
Here is the python code after you have pip install ffmpeg-python in your environment:
import ffmpeg
input_video = ffmpeg.input('./test/test_video.webm')
input_audio = ffmpeg.input('./test/test_audio.webm')
ffmpeg.concat(input_video, input_audio, v=1, a=1).output('./processed_folder/finished_video.mp4').run()
v=1:
Set the number of output video streams, that is also the number of video streams in each segment. Default is 1.
a=1: Set the number of output audio streams, that is also the number of audio streams in each segment. Default is 0.
For the details of ffmpeg.concat, check out: https://ffmpeg.org/ffmpeg-filters.html#concat.
You can check out more examples here: https://github.com/kkroening/ffmpeg-python/issues/281
Hope this helps!
PS.
If you are using MacOS and have the error:
FileNotFoundError: [Errno 2] No such file or directory: 'ffmpeg' while running the code, just brew install ffmpeg in your terminal.
You could use subprocess:
import subprocess
subprocess.run("ffmpeg -i video.mp4 -i audio.mp4 -c copy output.mp4")
You can also use fstrings to use variable names as input:
videofile = "video.mp4"
audiofile = "audio.mp4"
outputfile = "output.mp4"
codec = "copy"
subprocess.run(f"ffmpeg -i {videofile} -i {audiofile} -c {codec} {outputfile}")
import ffmpeg
input_video = ffmpeg.input("../resources/video_with_audio.mp4")
added_audio = ffmpeg.input("../resources/dance_beat.ogg").audio.filter('adelay', "1500|1500")
merged_audio = ffmpeg.filter([input_video.audio, added_audio], 'amix')
(ffmpeg
.concat(input_video, merged_audio, v=1, a=1)
.output("mix_delayed_audio.mp4")
.run(overwrite_output=True))
you can review this link https://github.com/kkroening/ffmpeg-python/issues/281#issuecomment-546724993
Added the following code:
https://github.com/russellstrei/combineViaFFMPEG
It walks the directory, finds ".mp4" files, adds it to the file to be used by ffmpeg, then executes the command.
for name in glob.glob(directory +"\\"+ '*.mp4'):
print(name)
file1 = open(processList, "a") # append mode
file1.write("file '" + name + "'\n")
file1.close()
execute()
def execute():
cmd = "ffmpeg -f concat -safe 0 -i " + processList + " -c copy "+ dir + "output.mp4"
os.system(cmd)

How to combine The video and audio files in ffmpeg-python

I'm trying to combine a video(with no sound) and its separate audio file
I've tried ffmpeg ffmpeg -i video.mp4 -i audio.mp4 -c copy output.mp4
and it works fine.
i'm trying to achieve the same output from ffmpeg-python but with no luck. Any help on how to do this?
I had the same problem.
Here is the python code after you have pip install ffmpeg-python in your environment:
import ffmpeg
input_video = ffmpeg.input('./test/test_video.webm')
input_audio = ffmpeg.input('./test/test_audio.webm')
ffmpeg.concat(input_video, input_audio, v=1, a=1).output('./processed_folder/finished_video.mp4').run()
v=1:
Set the number of output video streams, that is also the number of video streams in each segment. Default is 1.
a=1: Set the number of output audio streams, that is also the number of audio streams in each segment. Default is 0.
For the details of ffmpeg.concat, check out: https://ffmpeg.org/ffmpeg-filters.html#concat.
You can check out more examples here: https://github.com/kkroening/ffmpeg-python/issues/281
Hope this helps!
PS.
If you are using MacOS and have the error:
FileNotFoundError: [Errno 2] No such file or directory: 'ffmpeg' while running the code, just brew install ffmpeg in your terminal.
You could use subprocess:
import subprocess
subprocess.run("ffmpeg -i video.mp4 -i audio.mp4 -c copy output.mp4")
You can also use fstrings to use variable names as input:
videofile = "video.mp4"
audiofile = "audio.mp4"
outputfile = "output.mp4"
codec = "copy"
subprocess.run(f"ffmpeg -i {videofile} -i {audiofile} -c {codec} {outputfile}")
import ffmpeg
input_video = ffmpeg.input("../resources/video_with_audio.mp4")
added_audio = ffmpeg.input("../resources/dance_beat.ogg").audio.filter('adelay', "1500|1500")
merged_audio = ffmpeg.filter([input_video.audio, added_audio], 'amix')
(ffmpeg
.concat(input_video, merged_audio, v=1, a=1)
.output("mix_delayed_audio.mp4")
.run(overwrite_output=True))
you can review this link https://github.com/kkroening/ffmpeg-python/issues/281#issuecomment-546724993
Added the following code:
https://github.com/russellstrei/combineViaFFMPEG
It walks the directory, finds ".mp4" files, adds it to the file to be used by ffmpeg, then executes the command.
for name in glob.glob(directory +"\\"+ '*.mp4'):
print(name)
file1 = open(processList, "a") # append mode
file1.write("file '" + name + "'\n")
file1.close()
execute()
def execute():
cmd = "ffmpeg -f concat -safe 0 -i " + processList + " -c copy "+ dir + "output.mp4"
os.system(cmd)

ffmpeg in python script

I would like to run the following command in a python script, I also want to make it loop over several videos in a folder. This is the command I want to run.
ffmpeg -i mymovie.avi -f image2 -vf fps=fps=1 output%d.png
I want to fit it in something like this:
import ffmpy
import os
path = './Videos/MyVideos/'
for filename in os.listdir(path):
name = filename.replace('.avi','')
os.mkdir(os.path.join(path,name))
*ffmpeg command here*
I found a wrapper for ffmpeg called ffmpy, could this be a solution?
From a brief look at FFMPY, you could do this using ffmpy.FFmpeg, as that allows any and all FFMPEG command line options, including -f. -- Click the link for documentation.
You could do the FFMPEG command with os.system. You'll need to import OS anyway to iterate through the files.
You would need to iterate through all the files in a directory though. This would be the more challenging bit, it's quite easy with a for loop though.
for filename in os.listdir(path):
if (filename.endswith(".mp4")): #or .avi, .mpeg, whatever.
os.system("ffmpeg -i {0} -f image2 -vf fps=fps=1 output%d.png".format(filename))
else:
continue
The above code iterates through the directory at path, and uses command prompt to execute your given FFMPEG command, using the filename (if it's a video file) in place of mymovie.avi
Dont have reputation to comment, hence adding another response.
Another version of ocelot's answer with the more readable f-string syntax of python -
for filename in os.listdir(path):
if (filename.endswith(".mp4")): #or .avi, .mpeg, whatever.
os.system(f'ffmpeg -i {filename} -f image2 -vf fps=fps=1 output%d.png')
else:
continue
Try pydemux in https://github.com/Tee0125/pydemux. Pydemux module can extract video frames as in Pillow Image format
from PyDemux import Video
v = Video.open('video.mov')
i = 0
while True:
im = v.get_frame()
if im is None:
break
im.save('output%d.png'%i)
i = i + 1
This is a way to use ffmpeg in a python script, e.g. for extracting the last 10 seconds of every video:
ffmpeg -sseof -10 -i input.mp4 output.mp4
To apply this to a whole folder of mp4 files:
from pathlib import Path
import os
suffix = ".mp4"
input_path= Path.home() / "Desktop/foo"
file_paths= [subp for subp in input_path.rglob('*') if suffix == subp.suffix]
file_paths.sort()
output_path = Path.home() / "Desktop/foo/new"
output_path.mkdir(parents=True, exist_ok=True)
for file_p in file_paths:
input = str(file_p)
output = str( output_path / file_p.name )
command = f"ffmpeg -sseof -10 -i {input} {output}"
print(command)
os.system(command)

Categories

Resources