「Python|音视频处理|场景案例」如何获取音视频中声音片段的起止时间?

本文介绍了如何使用Python的moviepy库结合ffmpeg工具来找出音视频中声音开始和结束的位置,以及识别多个单词音频的起止时间。通过检查音频每个时间点的音量并设定阈值,确定无声和有声的部分,从而实现音频的分割。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要介绍如何使用python的第三方库moviepy找出音视频中声音开始出现的位置以及声音结束的位置。

场景描述

  • 假设我们有一段音频,音频开始有一段无声片段,音频结束也有一段无声片段,我们需要知道开头无声片段的结束位置和结束无声片段的开始位置,或者换句话说,我们需要知道在第几秒开始第一次出现声音,在第几秒位置是最后一次声音,这样就可以去除首末的无声部分。
  • 更进一步,假设我们有一段单词发音音频,整个音频读了多个单词,我们希望得到各个片段的起始时间和结束时间(之后可以根据时间将音频切分为单个单词的发音音频)

我们使用音视频软件打开一段音频,可以看到音频声音结构如下,分为4个有声部分,开头和结束都有一小段无声部分。
在这里插入图片描述

各个音频片段的开始时间和结束时间如下:

音频片段目测开始时间目测结束时间
第一段0.18s4.06s
第二段5.20s5.27s
第三段8.21s9.00s
第四段10.16s18.6s

接下来我们就尝试编写一段程序找出上述四个片段的起止时间

准备工作

  • 处理音视频的时候,可以使用强大的ffmpeg工具完成各种各样的操作
  • python中可以使用底层封装了ffmpeg的第三方库moviepy来快速完成一些常见的音视频处理

所以,我们需要安装ffmpeg(moviepy需要使用),moviepy两个库,

解决方案

想要找出一段音频中在第几秒开始出现声音,我们可以从音频开始以很小的时间间隔检查每一个时间点上的音频音量,如果音频音量等于0(或者小于某个音量值),则认为这个时间点是无声的,检查到第一个不是无声的时间点,就是音频开始出现声音的位置。
同理,如果我们要找出单词带读音频中各个单词的起止时间,则找到第一次出现声音的位置和声音出现后第一次消失的位置就是这个单词音频的起止时间。

我们查找moviepy中是否已经有现成的查看音频音量的方法,可以找到.max_volume()方法可以得到一段音频中的最大音量,使用这个方法,如果一段极短的音频的最大音量是0(或者小于某个值)就认为这个时间段的音频是无声的,则可以设计如下操作:

  • (导入我们要用的moviepy):from moviepy.editor import *
  • 读取音频数据:
    • audio = AudioFileClip("D:/45.mp3")
    • 如果是视频文件, 则使用audio = VideoFileClip("D:/视频文件名.mp4").audio获取视频的音频数据
  • 音频都是从0s开始的,结束时间可以通过audio.end得到
  • 假设我们检查的时间间隔是0.1s,则可以分成audio.end / 0.1个需要检查的时间片段
  • 截取某一个片段的音频可以使用audio_clip = audio.subclip(0, 0.1)
  • 检查获取最大音量:audio_clip.max_volume()

源代码

import math
from typing import List
from moviepy.editor import *


def mark_each_duration_sound_or_silent(audio_clip, window_size=0.1, volume_threshold=0.01) -> List[bool]:
    """标记每一个检查区间的音频片段是有声还是无声"""

    window_amount = math.floor(audio_clip.end / window_size)
    window_is_silent = []
    for i in range(window_amount):
        s = audio_clip.subclip(i * window_size, (i + 1) * window_size)
        v = s.max_volume()
        window_is_silent.append(v < volume_threshold)
    return window_is_silent


def find_sound_appear_and_disappear_position(window_is_silent, window_size=0.1, ease_in=0.25):
    """找出每一个「无声到有声」和「有声到无声」的时间点作为声音片段的起止时间"""
    
    speaking_start = 0
    speaking_end = 0
    sound_intervals = []
    for window_num in range(1, len(window_is_silent)):
        last_point = window_is_silent[window_num - 1]
        current_point = window_is_silent[window_num]

        # 出现上一个时间点无声, 当前时间点有声, 当前时间点就是声音开始位置
        if last_point and not current_point:
            speaking_start = window_num * window_size

        # 出现上一个时间点有声, 当前时间点无声, 当前时间点就是声音结束位置
        # 有了声音的开始位置和结束位置,就有了一个声音片段的起止区间
        if not last_point and current_point:
            speaking_end = window_num * window_size
            new_speaking_interval = [speaking_start - ease_in, speaking_end + ease_in]
            if new_speaking_interval[0] < 0:
                new_speaking_interval[0] = 0

            # 当时间间隔(window_size)过小而声音渐入区间(ease in)过大时, 会出现时间片段重叠的问题,这种情况需要合并两个区间
            need_to_merge = len(sound_intervals) > 0 and sound_intervals[-1][1] > new_speaking_interval[0]
            if need_to_merge:
                merged_interval = [sound_intervals[-1][0], new_speaking_interval[1]]
                sound_intervals[-1] = merged_interval
            else:
                sound_intervals.append(new_speaking_interval)

    return sound_intervals


def find_sound_intervals(audio_clip, window_size=0.1, volume_threshold=0.01, ease_in=0.25):
    # First, iterate over audio to find all silent windows.
    window_is_silent = mark_each_duration_sound_or_silent(audio_clip, window_size, volume_threshold)
    return find_sound_appear_and_disappear_position(window_is_silent, window_size, ease_in)


audio = AudioFileClip("D:/45.mp3")
print(f"Check With Default Options: {find_sound_intervals(audio)}")
"""输出结果:
Check With Default Options: [[0.25, 4.3500000000000005], [5.3500000000000005, 6.15], [8.450000000000001, 9.25], [10.25, 18.55]]
"""

找到了各个声音片段的起止时间,我们就可以使用截取音视频的方法将各个片段分别保存到本地磁盘了,快去试试吧~

好书推荐:

好课推荐:

写文不易,如果对你有帮助的话,来一波点赞、收藏、关注吧~👇

<think>好的,用户的问题是如何从视频中提取音频并将其转换为文字文档。我需要结合提供的引用内容来给出详细的步骤和工具推荐。首先,用户需要提取音频,引用中提到了使用ffmpeg的命令行工具,比如引用5中的命令格式:ffmpeg -ss [start] -i [input] -to [end] -c copy [output],这可能用来剪切视频,但提取音频的话可能需要不同的参数。我应该解释如何用ffmpeg提取音频,比如转换为MP3或WAV格式。 接下来是转录部分。引用1提到了使用Google Docs的语音输入功能,通过播放视频音频并实时转录,但这种方法需要实时播放,可能不太方便。引用2推荐了Otter.ai,这个工具可以直接导入音频文件进行转录,可能更高效。引用3和4提到了PyAudioAnalysis和另一个示例,但看起来更偏向于音频分析而不是转录,不过引用4提到了高精度文本转录,可能需要进一步确认是否有相关工具。 然后,我需要整理步骤:第一步提取音频,使用ffmpeg或其他工具;第二步使用转录工具如Otter.ai、Google Docs或专业软件。还要考虑是否有开源或免费工具,比如利用Python库,但引用3中的PyAudioAnalysis主要做特征提取,可能不直接用于转录,但结合其他库如SpeechRecognition可能实现。不过用户可能更倾向于现成的解决方案,所以重点放在Otter.ai和Google Docs的方法上。 需要检查每个步骤的可行性和详细操作,比如提取音频的具体命令,转录时的注意事项,比如音频质量、背景噪音的影响。可能还需要提到处理时间音频的技巧,比如分段处理。另外,引用4提到了示例音频下载,但用户可能需要自己处理自己的文件,所以不需要那个链接。最后,确保回答结构清晰,分步骤说明,并推荐合适的工具,同时引用正确的引用来源。</think>### 分步解决方案:从视频提取音频并转录为文字 #### **步骤1:从视频中提取音频** 使用工具 **`ffmpeg`**(开源命令行工具)将视频中的音频提取为独立文件(如MP3/WAV)。 **操作示例**: ```bash # 提取完整音频(格式为MP3) ffmpeg -i input_video.mp4 -q:a 0 -map a output_audio.mp3 # 提取指定时间段音频(如从00:01:30到00:05:00) ffmpeg -ss 00:01:30 -i input_video.mp4 -to 00:03:30 -q:a 0 -map a output_clip.mp3 ``` - **参数说明**: - `-i`:输入视频文件 - `-map a`:仅提取音频流 - `-q:a 0`:保持最高音频质量 - `-ss` 和 `-to`:剪切起止时间[^5] --- #### **步骤2:将音频转录为文字文档** 根据需求选择以下工具: 1. **Google Docs语音输入(免费,需实时播放音频)** - 打开Google Docs,点击**工具 > 语音输入**,播放提取的音频文件,系统会通过麦克风实时转录[^1]。 - **限制**:需外放音频且环境安静,适合短音频(<1小时)。 2. **Otter.ai(自动识别,支持长音频)** - 上传音频文件(MP3/WAV),Otter.ai会自动生成带时间戳的文字稿,支持编辑和导出[^2]。 - **优势**:支持多语言、噪音过滤和关键词搜索。 3. **Python语音识别库(需编程基础)** - 使用 `SpeechRecognition` 库调用Google API: ```python import speech_recognition as sr recognizer = sr.Recognizer() with sr.AudioFile("output_audio.wav") as source: audio_data = recognizer.record(source) text = recognizer.recognize_google(audio_data, language="zh-CN") with open("transcript.txt", "w") as f: f.write(text) ``` - **注意**:需将音频转换为WAV格式(16kHz采样率),且单文件不超过1小时[^3][^4]。 --- #### **步骤3:优化转录结果** - **降噪处理**:使用Audacity或Adobe Audition减少背景噪音。 - **分段校对**:长音频按时间切割后分批处理(参考`ffmpeg`分段命令)。 - **专业工具**:需要高精度转录时,可选择讯飞听见或腾讯云语音识别(付费API)。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明仔的阳光午后

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值