is there any way i could get finer control over bitrate when encoding a file? (would this be different depending on the encoder im using?) like decreasing or increasing the bitrate with some sort of math function or something? also how would i google things like this, when i try to search questions like this i get streaming bitrate settings back which kind of isnt what i want
#ffmpeg bitrate control
37 messages · Page 1 of 1 (latest)
You want exact control over bits per frame?
Probably not exactly
You MIGHT be able to do some fuckery with i-frames and lossless merging
Fascinating question though, I will look into this later
thank you frost my goat
i am planning on using something like this for a musical piece for one of my classes, so if its possible to do something like this with aac or opus or similar that would be perfect for my usecase
I believe you could do this with webm at the very least
or somehow inject something into the encoder to make it target a different bitrate/quality as time passes
@small tapir IVE DONE IT
solution is to segment the file
then reeencode all separately
then change the bitrate to a custom equation
import os
inFile = "gun.flac"
# inFile = input("Input file: ")
nameFile = "out"
extension = 'flac'
# extension = input("Output file type (no .): ")
timeSplit = 1
# timeSplit = float(input("Split every n seconds: "))
os.system(f"ffmpeg -stats_period 0.05 -hide_banner -loglevel error -y -i {inFile} -c copy -flags +global_header -segment_time {timeSplit} -f segment {nameFile}%d.{extension}")
numOuts = int(input("Last output number?"))
# linear decrease in bitrate
startBitrate = 128
for i in range(numOuts+1):
# command = f'ffmpeg -stats_period 0.05 -hide_banner -loglevel error -y -i {nameFile}{i}.{extension} -c:a aac -b:a {int(startBitrate-(startBitrate*i/numOuts))}k {nameFile}{i}new.aac'
command = f'ffmpeg -stats_period 0.05 -hide_banner -loglevel error -y -i {nameFile}{i}.{extension} -c:a aac -b:a {int(startBitrate*(numOuts-i)/numOuts)}k {nameFile}{i}new.aac'
print(command)
os.system(command)
os.remove(f"{nameFile}{i}.{extension}")
with open("output.txt", "a") as f:
for i in range(numOuts+1):
print(f"file '{nameFile}{i}new.aac'", file=f)
command = f'ffmpeg -y -stats_period 0.05 -hide_banner -loglevel error -f concat -i output.txt -c copy concatenated.aac'
os.system(command)
for i in range(numOuts+1):
os.remove(f"{nameFile}{i}new.aac")
os.remove("output.txt")
for "last output?" enter the highest number of output.flac (or whatever your extension is) that it generates
also edit the top variables as needed
output
currently just linear decrease in bitrate (so not a linear decrease in subjective quality)
you could adjust this to any equation you'd like
startBitrate/(i+1) gives exponential decay
THANK YOU FROST MY GOAT
its not fully working i lied
im working on it rn though
currently concatenation stops after like 1/3 of the file
i think the bitrate gets too low honestly
MEVERMIND
I was stupid
it was just fucking the duration up!
import os, math
inFile = "gun.flac"
# inFile = input("Input file: ")
nameFile = "out"
extension = 'flac'
# extension = input("Output file type (no .): ")
timeSplit = 6
# timeSplit = float(input("Split every n seconds: "))
os.system(f"ffmpeg -stats_period 0.05 -hide_banner -loglevel error -y -i {inFile} -c copy -flags +global_header -segment_time {timeSplit} -reset_timestamps 1 -f segment {nameFile}%d.{extension}")
numOuts = int(input("Last output number?"))
# linear decrease in bitrate
startBitrate = 256
for i in range(numOuts+1):
# command = f'ffmpeg -stats_period 0.05 -hide_banner -loglevel error -y -i {nameFile}{i}.{extension} -c:a aac -b:a {int(startBitrate-(startBitrate*i/numOuts))}k {nameFile}{i}new.aac'
command = f'ffmpeg -stats_period 0.05 -hide_banner -loglevel error -y -i {nameFile}{i}.{extension} -c:a aac -b:a {int(startBitrate/(i+1))}k -fflags +genpts {nameFile}{i}new.aac'
print(command)
os.system(command)
os.remove(f"{nameFile}{i}.{extension}")
# issue is not fixed by remuxing, but is fixed by not dropping the bitrate so low
# const bitrate of 50k had no issues
# is definitely caused by low bitrate - how to preserve info?
with open("output.txt", "a") as f:
for i in range(numOuts+1):
print(f"file '{nameFile}{i}new.aac'", file=f)
command = f'ffmpeg -y -stats -stats_period 0.05 -hide_banner -f concat -i output.txt -c copy concatenated.aac'
os.system(command)
for i in range(numOuts+1):
os.remove(f"{nameFile}{i}new.aac")
os.remove("output.txt")
input("done!")```
@small tapir fixed and working
currently does an exponential decrease in bitrate
maybe
it just divides bitrate by the segment number
first 6 seconds 256/1
next 256/2
next 256/3 etc
30 second example
what is ur usecase