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

在Django中用FFmpeg转WAV音频片段为FLAC时遇时长参数错误

Fixing "Invalid duration specification for ss" in Django FFmpeg FLAC Converter

Hey there! Let's break down why you're hitting that "Invalid duration specification for ss" error and get your FLAC conversion working properly.

What's Causing the Error?

Looking at your failed FFmpeg command, the issue is clear: you're passing entire lists of timestamps as strings to the -ss (start time) and -t (duration) parameters. FFmpeg can't parse something like [(0.006000000000000005, 1.03), ...] as a valid timestamp—it expects a single numerical value (like 0.006) for each parameter.

On top of that, your logic for adjusting start/end times was applying the padding to the entire list incorrectly, instead of processing each (start, end) pair individually.

Corrected FLACConverter Class

Here's a revised version of your class that fixes these issues, handles multiple segments properly, and cleans up temporary files safely:

import os
import tempfile
import subprocess
from pathlib import Path

class FLACConverter(object): # pylint: disable=too-few-public-methods
    """ Class for converting regions of an input audio file into a single FLAC audio file """
    def __init__(self, source_path, include_before=0.25, include_after=0.25):
        self.source_path = source_path
        self.include_before = include_before
        self.include_after = include_after

    def __call__(self, regions):
        try:
            print("Regions to convert to FLAC: {}".format(regions))
            temp_segment_files = []

            # Process each audio segment one by one
            for orig_start, orig_end in regions:
                # Adjust timestamps with padding (ensure start doesn't go below 0)
                adjusted_start = max(0.0, orig_start - self.include_before)
                adjusted_end = orig_end + self.include_after
                segment_duration = adjusted_end - adjusted_start

                # Create a temporary file for this segment
                temp_file = tempfile.NamedTemporaryFile(suffix='.flac', delete=False)
                temp_segment_files.append(temp_file.name)
                temp_file.close()

                # Build valid FFmpeg command for the segment
                ffmpeg_cmd = [
                    "ffmpeg",
                    "-ss", str(adjusted_start),  # Single valid start timestamp
                    "-t", str(segment_duration), # Single valid duration value
                    "-y",
                    "-i", self.source_path,
                    "-loglevel", "error",
                    temp_file.name
                ]

                # Execute the conversion
                subprocess.check_output(ffmpeg_cmd, shell=os.name == "nt")

            # Merge multiple segments into one FLAC file if needed
            if len(temp_segment_files) > 1:
                # Create a concat list file for FFmpeg
                concat_list_file = tempfile.NamedTemporaryFile(suffix='.txt', delete=False)
                with open(concat_list_file.name, 'w') as f:
                    for seg_file in temp_segment_files:
                        f.write(f"file '{Path(seg_file).resolve()}'\n")

                # Merge segments using FFmpeg's concat demuxer (lossless for FLAC)
                final_temp_file = tempfile.NamedTemporaryFile(suffix='.flac', delete=False)
                concat_cmd = [
                    "ffmpeg",
                    "-f", "concat",
                    "-safe", "0",
                    "-i", concat_list_file.name,
                    "-y",
                    "-loglevel", "error",
                    final_temp_file.name
                ]
                subprocess.check_output(concat_cmd, shell=os.name == "nt")

                # Clean up intermediate files
                os.unlink(concat_list_file.name)
                for seg_file in temp_segment_files:
                    os.unlink(seg_file)

                # Read the merged FLAC data
                with open(final_temp_file.name, 'rb') as f:
                    flac_data = f.read()
                os.unlink(final_temp_file.name)
            else:
                # Only one segment, read directly
                with open(temp_segment_files[0], 'rb') as f:
                    flac_data = f.read()
                os.unlink(temp_segment_files[0])

            print("Successfully processed audio regions to FLAC")
            return flac_data

        except KeyboardInterrupt:
            # Clean up temp files if user interrupts
            for file_path in temp_segment_files:
                if os.path.exists(file_path):
                    os.unlink(file_path)
            return None
        except subprocess.CalledProcessError as e:
            print(f"FFmpeg failed with error: {e}")
            # Clean up temp files on failure
            for file_path in temp_segment_files:
                if os.path.exists(file_path):
                    os.unlink(file_path)
            return None

Key Improvements

  • Per-segment processing: We loop through each (start, end) pair in your regions list, generating a valid FFmpeg command for each segment.
  • Valid timestamp parameters: Each -ss and -t gets a single numerical value (in seconds) that FFmpeg can parse correctly.
  • Segment merging: If you have multiple regions, we use FFmpeg's concat demuxer to merge them into a single FLAC file (this is lossless for FLAC, so no quality loss).
  • Safe cleanup: All temporary files are deleted even if the process is interrupted or fails, preventing leftover files from cluttering your system.

How to Use It

Just call the converter with your regions list like before:

converter = FLACConverter("path/to/your/audio.wav")
flac_data = converter([(0.006, 1.03), (2.054, 4.87)])

The returned flac_data is the binary content of the merged FLAC file, which you can save or use as needed.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:11:37