You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python调用FFmpeg检测视频实际音量(解决subprocess报错)

Fixing FFmpeg Volume Detection via Python Subprocess

Hey there! Let's tackle this problem together—detecting valid audio in your downloaded videos using FFmpeg and Python is totally doable, and we can fix those subprocess errors you're seeing.

Why You're Getting Those Errors

First, let's break down the two issues:

  1. "Output file #0 does not contain any stream": This usually happens when FFmpeg can't properly parse your command (often from passing the command as a single string instead of a list, leading to shell parsing issues) or when the output configuration is misinterpreted.
  2. "The handle could not be duplicated during redirection": This is a Windows-specific quirk when using shell=True with subprocess handle redirection. Avoiding shell=True and properly capturing stderr (where FFmpeg sends its diagnostic output) fixes this.

Working Solution Code

Here's a complete, tested script that runs the FFmpeg volume detection command correctly, captures the output, and extracts the average volume into a variable:

import subprocess
import re

def get_average_audio_volume(video_file_path):
    # Build the FFmpeg command as a list (avoids shell parsing errors)
    ffmpeg_cmd = [
        "ffmpeg",
        "-hide_banner",
        "-i", video_file_path,
        "-af", "volumedetect",
        "-vn",  # Disable video stream processing
        "-f", "null", "-"  # Send output to null device
    ]

    try:
        # Run the command, capture stderr (FFmpeg sends logs here, not stdout!)
        process_result = subprocess.run(
            ffmpeg_cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            check=True,
            text=True  # Get output as string directly, no need to decode bytes
        )

        # Extract the average volume using regex
        log_output = process_result.stderr
        volume_match = re.search(r"mean_volume:\s*(-?\d+\.?\d*)\s*dB", log_output)
        
        if volume_match:
            average_db = float(volume_match.group(1))
            return average_db
        else:
            print("Couldn't find average volume in FFmpeg's output.")
            return None

    except subprocess.CalledProcessError as e:
        print(f"FFmpeg failed to run: {e.stderr}")
        return None
    except Exception as e:
        print(f"Unexpected error: {str(e)}")
        return None

# Example usage
video_path = "testvideo.mp4"
avg_volume = get_average_audio_volume(video_path)

if avg_volume is not None:
    print(f"Average audio volume: {avg_volume} dB")
    # Define your threshold for "valid sound" (adjust as needed)
    if avg_volume > -60:
        print("✅ This video has valid audio.")
    else:
        print("❌ This video is silent or near-silent.")

Key Notes

  • Capture stderr, not stdout: FFmpeg sends all its diagnostic output (including the volumedetect results) to stderr, not stdout—this is a common gotcha!
  • Command as a list: Passing the FFmpeg command as a list of strings avoids shell parsing issues and the handle duplication error on Windows.
  • Threshold adjustment: A value around -91 dB means complete silence, but you can adjust the threshold (like -60 dB in the example) based on what counts as "valid sound" for your use case.
  • FFmpeg availability: Make sure FFmpeg is installed on your system and added to your PATH so Python can find it.

内容的提问来源于stack exchange,提问作者Sreenivasan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 16:20:29