Проверить, есть ли в видео звук, даже если у него есть аудиокодек?

Я новичок в промежуточном питоне, и я пытаюсь выяснить, есть ли звук в загруженном видео, каждое загружаемое видео имеет аудиокодек, но я хочу получить децибел звука, который звук имеет в этом конкретном видео.

Например, этот скрипт командной строки «FFmpeg» позволяет мне получить полную информацию:

ffmpeg -hide_banner -i testvideo.mp4 -af volumedetect -vn -f null - 2>&1

это дает следующий результат в моей командной строке (здесь пользователь Windows с win 11)

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'testvideo.mp4':

Metadata:

major_brand : mp42

minor_version : 0

compatible_brands: mp42mp41isomavc1

creation_time : 2022-04-12T23:21:45.000000Z

Duration: 00:00:40.58, start: 0.000000, bitrate: 4104 kb/s

Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080, 3846 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default)

Metadata:

creation_time : 2022-04-12T23:21:45.000000Z

handler_name : L-SMASH Video Handler

vendor_id : [0][0][0][0]

encoder : AVC Coding

Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 253 kb/s (default)

Metadata:

creation_time : 2022-04-12T23:21:45.000000Z

handler_name : L-SMASH Audio Handler

vendor_id : [0][0][0][0]

Stream mapping:

Stream #0:1 -> #0:0 (aac (native) -> pcm_s16le (native))

Press [q] to stop, [?] for help

Output #0, null, to 'pipe:':

Metadata:

major_brand : mp42

minor_version : 0

compatible_brands: mp42mp41isomavc1

encoder : Lavf59.35.100

Stream #0:0(und): Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s (default)

Metadata:

creation_time : 2022-04-12T23:21:45.000000Z

handler_name : L-SMASH Audio Handler

vendor_id : [0][0][0][0]

encoder : Lavc59.56.100 pcm_s16le

size=N/A time=00:00:40.55 bitrate=N/A speed=1.22e+03x

video:0kB audio:7608kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

[Parsed_volumedetect_0 @ 0000026609be08c0] n_samples: 3895296

[Parsed_volumedetect_0 @ 0000026609be08c0] mean_volume: -91.0 dB

[Parsed_volumedetect_0 @ 0000026609be08c0] max_volume: -91.0 dB

[Parsed_volumedetect_0 @ 0000026609be08c0] histogram_91db: 3895296

Как вы можете видеть, есть значения «parsed_volumedetect» с дБ, которые имеют среднее значение -91 дБ, что означает, что в аудио нет звука, то есть в видео есть звук, но нет звука.

Теперь я пытаюсь сделать то же самое в python, и я хочу получить только среднее значение громкости, которое будет храниться в переменной, чтобы я мог проверить, есть ли в видео какой-либо звук.

До сих пор я видел коды подпроцессов, но когда я пытаюсь запустить свой код в VS-Code - python 3.11:

import subprocess    
result = subprocess.run(["ffmpeg", "-hide_banner", "-af", "volumedetect", "-vn", "-f", "null", "testvideo1.mp4"],
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
    shell=True)
    print(result.stdout)

В нем говорится, что:

PS C:\Users\balaj\OneDrive\Documents\Programming language\python files> c:; cd 'c:\Users\balaj\OneDrive\Documents\Programming language\python files'; & 'C:\Python311\python.exe' 'c:\Users\balaj\.vscode\extensions\ms-python.python-2022.20.2\pythonFiles\lib\python\debugpy\adapter/../..\debugpy\launcher' '51760' '--' 'c:\Users\balaj\OneDrive\Documents\Programming language\python files\devproject\sample.py'

b"Output #0, null, to 'testvideo1.mp4':\r\nOutput file #0 does not contain any stream\r\n"

Буду признателен за любую оказанную помощь. Извините за длинный пост... TIA!!!

Просто быстрое обновление: Результат одинаков для видеофайлов со звуком (я тестировал в VLC) и без звука.

Еще одно обновление: Я изменил код subprocess.run на точно такой же, как я вызывал в окнах cmd:

result = subprocess.run(["ffmpeg", "-hide_banner","-i","testvideo-sound.mp4", "-af", "volumedetect", "-vn", "-f", "null", "-2>&1"]

Теперь результат такой:

b'The handle could not be duplicated\r\nduring redirection of handle 1.\r\n'
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, это работает для меня. Я попробовал это с несколькими разными видеофайлами (mp4), которые у меня были.

import subprocess
import re

files = [
    # list of file paths
]

def find_volume(s):
    # regex to find volume in a string
    m = re.search("(?:max_volume: )(?P<volume>.+ dB)", s, flags=re.IGNORECASE)
    
    if not m:
        return None

    return m.groupdict()["volume"]

    

for filepath in files:
    r = subprocess.run(f'ffmpeg -i "{filepath}" -filter:a volumedetect -f null /dev/null',
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            shell=True
    )
    # "volume" will be either None or a string;
    # if it is none, we go to do to the "else" body
    # instead, because None if 'falsy'.
    if volume := find_volume(r.stdout.decode("utf-8")):
        print(f'Video file "{filepath}" has a max volume of {volume}')
    else:
        print(f'Video file "{filepath}" has no audio')

Другие вопросы по теме