#ffmpeg bitrate control

37 messages · Page 1 of 1 (latest)

small tapir
#

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

slate pawn
#

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

small tapir
#

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

slate pawn
#

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

slate pawn
#

@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

#

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

small tapir
slate pawn
#

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