python - 如何在 Python 中检查视频是否有声音?
问题描述
我只想知道True
视频是否有音频或False
没有音频。
我觉得我几乎在那里使用子流程。
我获取有关正在运行的视频文件ffprobe
并将结果拆分为列表的信息。
我尝试匹配列表中包含或不包含音频的字符串,但这并没有给我一致的结果。
from subprocess import Popen, PIPE
import subprocess
b = '/path/to/mp4'
'0:1' in str(subprocess.run(['ffprobe', b], stdout=PIPE, stderr=PIPE).stderr.split()[-20])
上面的行检查视频文件中最后一行的第 20 个是否有第二个流。就像我说的,并不总是一致的。
我只是在请求或解析我从ffmprobe
.
这是返回的所有内容,ffprobe
而不仅仅是最后一项的第 20 个。
b = '/path/to/mp4'
subprocess.run(['ffprobe', b], stdout=PIPE, stderr=PIPE).stderr.split()
返回...
[b'ffprobe',
b'version',
b'4.2.4-1ubuntu0.1',
b'Copyright',
b'(c)',
b'2007-2020',
b'the',
b'FFmpeg',
b'developers',
b'built',
b'with',
b'gcc',
b'9',
b'(Ubuntu',
b'9.3.0-10ubuntu2)',
b'configuration:',
b'--prefix=/usr',
b'--extra-version=1ubuntu0.1',
b'--toolchain=hardened',
b'--libdir=/usr/lib/x86_64-linux-gnu',
b'--incdir=/usr/include/x86_64-linux-gnu',
b'--arch=amd64',
b'--enable-gpl',
b'--disable-stripping',
b'--enable-avresample',
b'--disable-filter=resample',
b'--enable-avisynth',
b'--enable-gnutls',
b'--enable-ladspa',
b'--enable-libaom',
b'--enable-libass',
b'--enable-libbluray',
b'--enable-libbs2b',
b'--enable-libcaca',
b'--enable-libcdio',
b'--enable-libcodec2',
b'--enable-libflite',
b'--enable-libfontconfig',
b'--enable-libfreetype',
b'--enable-libfribidi',
b'--enable-libgme',
b'--enable-libgsm',
b'--enable-libjack',
b'--enable-libmp3lame',
b'--enable-libmysofa',
b'--enable-libopenjpeg',
b'--enable-libopenmpt',
b'--enable-libopus',
b'--enable-libpulse',
b'--enable-librsvg',
b'--enable-librubberband',
b'--enable-libshine',
b'--enable-libsnappy',
b'--enable-libsoxr',
b'--enable-libspeex',
b'--enable-libssh',
b'--enable-libtheora',
b'--enable-libtwolame',
b'--enable-libvidstab',
b'--enable-libvorbis',
b'--enable-libvpx',
b'--enable-libwavpack',
b'--enable-libwebp',
b'--enable-libx265',
b'--enable-libxml2',
b'--enable-libxvid',
b'--enable-libzmq',
b'--enable-libzvbi',
b'--enable-lv2',
b'--enable-omx',
b'--enable-openal',
b'--enable-opencl',
b'--enable-opengl',
b'--enable-sdl2',
b'--enable-libdc1394',
b'--enable-libdrm',
b'--enable-libiec61883',
b'--enable-nvenc',
b'--enable-chromaprint',
b'--enable-frei0r',
b'--enable-libx264',
b'--enable-shared',
b'libavutil',
b'56.',
b'31.100',
b'/',
b'56.',
b'31.100',
b'libavcodec',
b'58.',
b'54.100',
b'/',
b'58.',
b'54.100',
b'libavformat',
b'58.',
b'29.100',
b'/',
b'58.',
b'29.100',
b'libavdevice',
b'58.',
b'8.100',
b'/',
b'58.',
b'8.100',
b'libavfilter',
b'7.',
b'57.100',
b'/',
b'7.',
b'57.100',
b'libavresample',
b'4.',
b'0.',
b'0',
b'/',
b'4.',
b'0.',
b'0',
b'libswscale',
b'5.',
b'5.100',
b'/',
b'5.',
b'5.100',
b'libswresample',
b'3.',
b'5.100',
b'/',
b'3.',
b'5.100',
b'libpostproc',
b'55.',
b'5.100',
b'/',
b'55.',
b'5.100',
b'Input',
b'#0,',
b'mov,mp4,m4a,3gp,3g2,mj2,',
b'from',
b"'/media/iii/Q2/tor/Reddit/Subs/unexpected/l2aifial2ir51.mp4':",
b'Metadata:',
b'major_brand',
b':',
b'isom',
b'minor_version',
b':',
b'512',
b'compatible_brands:',
b'isomiso2avc1mp41',
b'encoder',
b':',
b'Lavf58.29.100',
b'Duration:',
b'00:00:16.27,',
b'start:',
b'0.000000,',
b'bitrate:',
b'1341',
b'kb/s',
b'Stream',
b'#0:0(und):',
b'Video:',
b'h264',
b'(Main)',
b'(avc1',
b'/',
b'0x31637661),',
b'yuv420p,',
b'384x480',
b'[SAR',
b'1:1',
b'DAR',
b'4:5],',
b'1205',
b'kb/s,',
b'30',
b'fps,',
b'30',
b'tbr,',
b'12k',
b'tbn,',
b'60',
b'tbc',
b'(default)',
b'Metadata:',
b'handler_name',
b':',
b'Bento4',
b'Video',
b'Handler',
b'Stream',
b'#0:1(und):',
b'Audio:',
b'aac',
b'(LC)',
b'(mp4a',
b'/',
b'0x6134706D),',
b'48000',
b'Hz,',
b'stereo,',
b'fltp,',
b'128',
b'kb/s',
b'(default)',
b'Metadata:',
b'handler_name',
b':',
b'Bento4',
b'Sound',
b'Handler']
我还尝试将此函数从返回视频文件持续时间的函数修改为返回True
或返回False
音频的函数,因为这可能是获取布尔值的一种不那么老套的方法。尝试使用这些不同的选项时,我有点不知所措。
def get_length(filename):
result = subprocess.run(["ffprobe", "-v", "error", "-show_entries",
"format=duration", "-of",
"default=noprint_wrappers=1:nokey=1", filename],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
return float(result.stdout)
解决方案
基于先前的答案,这将检查每个流以查看是否至少有一个具有“音频”类型的编解码器。请注意,音频流可能存在但无声,在这种情况下仍将返回 True。
from subprocess import check_output
import json
def has_audio_streams(file_path):
command = ['ffprobe', '-show_streams',
'-print_format', 'json', file_path]
output = check_output(command)
parsed = json.loads(output)
streams = parsed['streams']
audio_streams = list(filter((lambda x: x['codec_type'] == 'audio'), streams))
return len(audio_streams) > 0
推荐阅读
- java - 如何解决书面许可问题
- c++ - Boost Spirit 嵌套组件
- python - selenium.common.exceptions.WebDriverException:消息:未知错误:在 Selenium Python 中使用 screenshot_as_png 出现未处理的检查器错误
- swift - 选择自定义按钮后,NavigationLink 不会转换到新视图
- typescript - 用于提取嵌套记录中所有值的 TypeScript 类型
- conky - 如何在 .conkyrc 配置文件中写注释?
- php - php mysql 搜索文本
- python - 熊猫重复相当于 isna 总和
- django - Django查询,找到最大对象
- python - 没有在循环中产生