Python基于MoviePy實現(xiàn)一鍵提取視頻音頻并生成MP3
摘要
昨天, 我在讓一個小朋友給我整理一次培訓(xùn)的視頻的時候,我看到他把視頻文件放到剪映里面處理。
我以為他要干什么呢, 還很期待,結(jié)果他只是為了導(dǎo)出音頻而已。 于是就有了今天的這篇博客。
作為音視頻處理領(lǐng)域的常用需求,視頻轉(zhuǎn)音頻功能在內(nèi)容二次創(chuàng)作、語音分析等場景中應(yīng)用廣泛。本文基于MoviePy庫,手把手教大家實現(xiàn)跨平臺視頻轉(zhuǎn)MP3工具的開發(fā),涵蓋以下技術(shù)要點:
- 支持MP4/AVI/MOV等主流格式轉(zhuǎn)換
- 自動生成同路徑MP3文件
- 包含異常捕獲與資源管理機制
- 提供開箱即用的命令行版本
1. 技術(shù)方案設(shè)計
1.1 工具架構(gòu)流程圖

1.2 核心依賴說明
# 關(guān)鍵庫版本要求 moviepy==1.0.3 # 音視頻處理核心庫
MoviePy依賴 Numpy 、 imageio 、 Decorator 和 tqdm ,他們將在安裝MoviePy的同時自動安裝。運行平臺為Windows/Mac/Linux,并使用Python2.7以上的版本和Python3。
MoviePy依賴FFMPEG軟件對視頻進行讀寫。不用對此擔(dān)心,在你第一次使用MoviePy的時候,F(xiàn)FMPEG將會自動由ImageIO下載和安裝(不過需要花一些時間)。如果你想使用FFMPEG的特定版本,你可以設(shè)置FFMPEG_BINARY環(huán)境變量。
2. 核心代碼實現(xiàn)
2.1 音頻提取函數(shù)
# 導(dǎo)入 moviepy 庫中的 AudioFileClip 類,用于處理視頻文件
from moviepy.audio.io.AudioFileClip import AudioFileClip
# 導(dǎo)入 os 模塊,用于處理文件路徑相關(guān)操作
import os
def extract_audio_from_video(video_path, audio_path=None):
"""
從視頻中提取音頻。
參數(shù):
video_path (str): 視頻文件的路徑。
audio_path (str, 可選): 提取后音頻文件的保存路徑,若未提供,則默認與視頻文件同名,擴展名為 .mp3。
返回:
str: 提取后音頻文件的路徑。
"""
# 檢查視頻文件是否存在
if not os.path.isfile(video_path):
raise FileNotFoundError(f'指定的視頻文件不存在: {video_path}')
# 若未提供音頻保存路徑,則默認使用視頻文件同名且擴展名為 .mp3 的路徑
if audio_path is None:
audio_path = os.path.splitext(video_path)[0] + ".mp3"
print(f"提取的音頻路徑: {audio_path}")
try:
# 創(chuàng)建 AudioFileClip 對象,用于提取視頻中的音頻
with AudioFileClip(video_path) as audio_clip:
# 將提取的音頻保存到指定路徑
audio_clip.write_audiofile(audio_path, codec='mp3')
return audio_path
except Exception as e:
# 打印提取音頻時出現(xiàn)的錯誤信息
print(f"提取音頻時出錯: {e}")
# 拋出異常,讓調(diào)用者處理
raise
這里要特別說明: 如果你用過老版本的MoviePy, 你這可能知道這個寫法from moviepy.editor import AudioFileClip。 目前,田辛老師使用這個新版本,已經(jīng)不用再加上.editor這個部分了, 反而加上會報錯。正確的有兩種寫法:
from moviepy.audio.io.AudioFileClip import AudioFileClip
from moviepy import AudioFileClip
2.2 通過streamlit生成調(diào)用的圖形界面
2.2.1. 圖形界面layout
初期畫面

上傳文件

處理中

處理結(jié)束可以下載,也可以在線聽

2.2.2. 源代碼
import streamlit as st
import os
from datetime import datetime
from video_audio_extractor import extract_audio_from_video
from dotenv import load_dotenv
# 創(chuàng)建輸入和輸出目錄
def create_directories():
# 獲取當前日期,并格式化為 yyyymmdd 的字符串
today = datetime.now().strftime('%Y%m%d')
# 定義輸入目錄,將其設(shè)置為 'input' 文件夾下以當前日期命名的子文件夾
input_dir = os.path.join('input', today)
# 定義輸出目錄,將其設(shè)置為 'output' 文件夾下以當前日期命名的子文件夾
output_dir = os.path.join('output', today)
# 創(chuàng)建輸入目錄,如果目錄已存在則不會報錯
os.makedirs(input_dir, exist_ok=True)
# 創(chuàng)建輸出目錄,如果目錄已存在則不會報錯
os.makedirs(output_dir, exist_ok=True)
# 返回創(chuàng)建好的輸入目錄和輸出目錄路徑
return input_dir, output_dir
# 主函數(shù)
def main():
# 加載環(huán)境變量文件
# 若加載成功,繼續(xù)執(zhí)行后續(xù)操作;若失敗,顯示錯誤信息并終止程序
if not load_dotenv():
st.error("讀取配置文件失敗,請檢查配置文件是否存在或路徑是否正確")
return
# 創(chuàng)建輸入和輸出目錄
input_dir, output_dir = create_directories()
# 設(shè)置應(yīng)用標題
st.title('視頻提取音頻工具')
# 創(chuàng)建文件上傳組件,僅允許上傳指定類型的視頻文件
uploaded_file = st.file_uploader('請上傳視頻文件', type=['mp4', 'mov', 'avi'])
# 創(chuàng)建轉(zhuǎn)換按鈕
convert_button = st.button('轉(zhuǎn)換為音頻文件')
if uploaded_file is not None and convert_button:
try:
# 初始化進度條
progress_bar = st.progress(0)
# 獲取上傳文件的擴展名
file_extension = os.path.splitext(uploaded_file.name)[1]
# 生成帶有時間戳的新文件名
new_file_name = f'video_audio_extractor_{datetime.now().strftime("%Y%m%d_%H%M%S")}'
# 拼接視頻文件保存路徑
video_path = os.path.join(input_dir, f"{new_file_name}{file_extension}")
# 拼接音頻文件保存路徑
audio_path = os.path.join(output_dir, f"{new_file_name}.mp3")
print(audio_path)
# 保存上傳的視頻文件
with open(video_path, 'wb') as f:
f.write(uploaded_file.getbuffer())
# 更新進度條到 25%
progress_bar.progress(25)
# 調(diào)用提取音頻的函數(shù)
audio_path = extract_audio_from_video(video_path, audio_path)
# 更新進度條到 100%
progress_bar.progress(100)
# 顯示音頻保存成功的消息
st.success(f'音頻已保存至 {audio_path}')
# 提供音頻文件下載鏈接
with open(audio_path, 'rb') as audio_file:
st.download_button('下載音頻', audio_file, file_name=os.path.basename(audio_path))
# 顯示音頻播放組件
with open(audio_path, 'rb') as audio_file:
st.audio(audio_file, format='audio/mp3')
except Exception as e:
# 捕獲并顯示處理過程中出現(xiàn)的錯誤
st.error(f'處理過程中出錯: {e}')
if __name__ == '__main__':
main()3. 典型錯誤處理
| 錯誤類型 | 解決方案 |
|---|---|
| 解碼器缺失 | MoviePy依賴FFMPEG,如果沒有裝雖然它會自己下載,但是并不是最新版, 如果不可用的話,可以嘗試手動安裝最新版本,并設(shè)置環(huán)境變量Path |
| 內(nèi)存溢出 | 增加臨時目錄設(shè)置:os.environ["TEMP"] = "D:/temp" |
結(jié)語
本文完整實現(xiàn)了從視頻文件提取音頻的自動化工具,開發(fā)者可直接集成到媒體處理系統(tǒng)中。建議搭配FFmpeg官方文檔深入學(xué)習(xí)音視頻編解碼原理。
到此這篇關(guān)于Python基于MoviePy實現(xiàn)一鍵提取視頻音頻并生成MP3的文章就介紹到這了,更多相關(guān)Python MoviePy提取視頻音頻內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Tensorflow中查看權(quán)重的實現(xiàn)
今天小編就為大家分享一篇在Tensorflow中查看權(quán)重的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01
Python面向?qū)ο蟪绦蛟O(shè)計類的多態(tài)用法詳解
這篇文章主要介紹了Python面向?qū)ο蟪绦蛟O(shè)計類的多態(tài)用法,結(jié)合實例形式詳細分析了Python面向?qū)ο蟪绦蛟O(shè)計中類的多態(tài)概念、原理、用法及相關(guān)操作注意事項,需要的朋友可以參考下2019-04-04
實現(xiàn)python版本的按任意鍵繼續(xù)/退出
本文給大家簡單介紹了在windows以及l(fā)inux下實現(xiàn)python版本的按任意鍵繼續(xù)/退出功能,非常的簡單實用,linux下稍微復(fù)雜些,有需要的小伙伴可以參考下2016-09-09
淺談python的elementtree模塊處理中文注意事項
這篇文章主要介紹了淺談python的elementtree模塊處理中文注意事項,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03
pytorch 運行一段時間后出現(xiàn)GPU OOM的問題
這篇文章主要介紹了pytorch 運行一段時間后出現(xiàn)GPU OOM的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06

