i'm kinda noob with Python but i managed to make this code to encode multiple videos files from a folder to H265, everything woks fine exept for the output name.
Actually the output name keep the old file extension with the new one like this "MyMovie.mov.mp4" and i want it to be named like this "MyMovie.mp4" is there any way to exclude the original file extension from the output file?
import os, sys, re
input_folder= '/content/drive/My Drive/Videos'
output_folder= '/content/drive/My Drive/Videos/X265'
quality_setting = '30'
file_type = 'mp4
my_suffixes = (".mp4", ".mov", ".mkv", ".avi", ".ts", ".flv", ".webm", ".wmv", ".mpg", ".m4v", ".f4v")
from pathlib import Path
Path(output_folder).mkdir(parents=True, exist_ok=True)
for filename in os.listdir(my_folder):
if (filename.endswith(my_suffixes)):
cmd = !ffmpeg -v quiet -stats -hwaccel cuvid -i "$input_folder/{filename}" -metadata comment="X265-QF$quality_setting-AAC" -c:v hevc_nvenc -preset:v slow -rc vbr -cq $quality_setting -c:a aac -b:a 160k "$output_folder/{filename}.$file_type"
Ps: This code is used on Google Colab that's why i need this with python.
In you for-loop you check if filename ends with one of the extensions listed above. So filename contains something like output.mp4 then in cmd you add .$file_type to the end of your command which is set to .mp4. I think you should remove that last part so you will only have the extension contained in filename.
I found a way i used rpartition to cut the file extension
cmd = !ffmpeg -v quiet -stats -hwaccel cuvid -i "$input_folder/{filename}" -metadata comment="X265-QF$quality_setting-AAC" -c:v hevc_nvenc -preset:v slow -rc vbr -cq $quality_setting -c:a aac -b:a 160k "$output_folder/{filename.rpartition('.')[0]}.$file_type"
Related
I'm trying to build a GUI with Tkinter where a set of images is converted, via press of a button, to an .mp4 video.
When I run the following from the command line, all is well:
> "ffmpeg -r 5 -i ptimage%03d -crf 20 animation.mp4"
However, in Python, the following gives me an error that I think is related to passing the % in the argument:
commandString = "ffmpeg -r 5 -i ptimage%03d -crf 20 animation.mp4"
args = shlex.split(commandString)
p = subprocess.run(args)
The error I get is ptimage%03d: No such file or directory. I'm 99% sure I'm running the command from the right directory; when I run the same command replacing ptimage%03d with ptimage000.jpg, a specific image the list, I get a (really short) video successfully.
I've tried escaping the % with \%, but that doesn't help.
Any ideas?
You omitted the file extension. Use ptimage%03d.jpg, not ptimage%03d. With ptimage%03d ffmpeg is expecting files named ptimage000 ,ptimage001, etc.
ffmpeg -framerate 5 -i ptimage%03d.jpg -crf 20 animation.mp4
Unrelated notes: Some players (YouTube excluded) can't handle such a low frame, so consider adding the -r 10 output option. Same with the chroma subsampling: consider adding -vf format=yuv420p output option.
I would like to process .wav files in Python. Particularly, I would like to perform following operation
sox input.wav -c 1 -r 16000 output.wav
in every .wav file in my folder. My code is below:
#!/usr/bin/python
# encoding=utf8
# -*- encoding: utf -*-
import glob
import subprocess
segments= []
for filename in glob.glob('*.wav'):
new_filename = "converted_" + filename
subprocess.call("sox" + filename + "-c 1 -r 16000" + new_filename, shell=True)
However, it is not working as expected that it's not calling my command.
When you write
subprocess.call("sox" + filename + "-c 1 -r 16000" + new_filename, shell=True)
what's actually going to be executed for an exemplary TEST.WAV file looks like this:
soxTEST.WAV-c 1 -r 16000converted_TEST.WAV
So you're missing the spaces in between. A nice solution using Python's f-strings (Formatted string literals) would be something like this:
subprocess.call(f"sox {filename} -c 1 -r 16000 {new_filename}", shell=True)
However, I'd recommend switching over to subprocess.run and disregarding the shell=True flag:
subprocess.run(["sox", filename, "-c 1", "-r 16000", new_filename])
More information also at the docs https://docs.python.org/3/library/subprocess.html
Note: Read the Security Considerations section before using shell=True.
I want to create an automated way to cut .mp3 files to 45 seconds.
So far I have been able to use ffmpeg to cut the audio to 45 seconds with this command:
ffmpeg -t 45 -i input.mp3 -acodec copy output.mp3
However this does not actually speed anything up, as if I have to do this with each file I might as well use audacity. I know that I should be able to use a .bat file to create a loop for this, however I don't know how to set up the loop. In python I would create a list of the file names in my directory with listdir:
fileNames = listdir(path),
and then create a for loop:
(something like
i = 1
for fileName in fileNames:
x = 2 * int(i)
ffmpeg -t 45 -i str(fileName)+'.mp3' -acodec copy str(x)+'.mp3'
that)
However I don't know how to create something like this in a .bat file. Some help with this, or a way to achieve this in python, would be much appreciated.
You can try using below script. Save the code into a *.bat file in the folder where you have your mp3 songs and execute it and it will process all your songs.
#ECHO OFF
setlocal enableextensions enabledelayedexpansion
set /a count = 1
for %%f in (*.mp3) do (
set "output=!count!.mp3"
ffmpeg -t 45 -i %%f -acodec copy !output!
set /a count+=1
)
endlocal
I have a folder with around 10 different mov files. I would like to add the filename as text on each of the videos using ffmpeg in a bat file. Could someone help me achieve this please?
EDIT:
I have tried using
#ECHO OFF&Setlocal EnableDelayedExpansion
Set INPUT=E:\\Users\\Oli\\Documents\\Projects\\v1.3.0\\downloads3
Set OUTPUT=E:\\Users\\Oli\\Documents\\Projects\\v1.3.0\\downloads3
for %%a in ("%INPUT%\*.*") DO (
set "filename=%%~na"
ffmpeg -i "%%a" -vf "drawtext=text=!fileName:.= !:x=105:y=120:fontfile=E:\\Users\\Oli\\Documents\\Projects\\v1.3.0\\downloads3\\impact.ttf:fontsize=25:fontcolor=white" -b:v 1M -r 60 -b:a 320k -ar 48000 -crf 17 "%%~na.mov"
)`
But it gives me the error:
Cannot find a valid font for the family Sans
[AVFilterGraph # 0000026eb75a9f40] Error initializing filter 'drawtext' with args 'text=FileName1'
Error reinitializing filters!
Failed to inject frame into filter network: No such file or directory
Error while processing the decoded data for stream #0:0
Let's get rid of the variable assignment and simply use variable expansion to set the name. Also, though it will still work, remove the secondary backslash because it is not needed and looks ugly, lastly, always wrap set variables for paths in double quotes. Give this a try.
#echo off
set "INPUT=E:\Users\Oli\Documents\Projects\v1.3.0\downloads3"
set "OUTPUT=E:\Users\Oli\Documents\Projects\v1.3.0\downloads3"
for %%a in ("%INPUT%\*.*") do (
ffmpeg -i "%%~a" -vf "drawtext=text=%%~na:x=105:y=120:fontfile=%~dp0impact.ttf:fontsize=25:fontcolor=white" -b:v 1M -r 60 -b:a 320k -ar 48000 -crf 17 "%%~na.mov"
)
I was wondering how I could go about doing telling FFMPEG where to save files it converts, it keeps making the files save way too deep in my computer.
check_output("ffmpeg -i " + location + " -vn -ar 44100 -ac 1 -b:a 32k -f wav audio.wav", shell=True)
I use that in my program to convert the files to wav.
The question is totally unrelated to python.
I suggest stopping using shell=True, because that invokes a shell to call your subprocess, adding useless overhead (invoke a process to invoke another process). Another advantage is that it allows you to provide the command line as a list of parameters, which frees you from quote/space hell and is simpler.
That said, just add the folder to the destination filename and it will be generated there:
filename = 'audio.wav'
destination = r'C:\Some\Folder'
subprocess.check_output(["ffmpeg",
"-i", location,
"-vn",
"-ar", "44100",
"-ac", "1",
"-b:a", "32k",
"-f", "wav",
os.path.join(destination, filename)
])