亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python調(diào)用ffmpeg截取視頻片段并進(jìn)行批量處理的方法

 更新時(shí)間:2025年04月28日 10:04:05   作者:BO_S__  
在多媒體處理領(lǐng)域,尤其是視頻和音頻處理,Python社區(qū)一直缺乏一個(gè)強(qiáng)大且易用的庫(kù),幸運(yùn)的是,ffmpeg-python庫(kù)的出現(xiàn)填補(bǔ)了這一空白,它是一個(gè)Python綁定,使得Python開(kāi)發(fā)者能夠輕松地處理視頻和音頻文件,本文介紹了如何使用Python調(diào)用ffmpeg截取視頻片段并進(jìn)行批量處理方法

背景

我本地下載了一些番劇,但是片頭片尾無(wú)用還占空間,因此決定使用ffmpeg對(duì)視頻切割,只保留中間的正片內(nèi)容。

用到的ffmpeg命令

ffmpeg中文文檔:https://ffmpeg.github.net.cn/ffmpeg.html

?????先說(shuō)用到的ffmpeg命令,你可以自行在cmd窗口中執(zhí)行以處理單個(gè)視頻。

  1. 獲取視頻時(shí)長(zhǎng):ffprobe -show_entries format=duration -v error -select_streams v:0 <視頻路徑>
    示例輸出:
[FORMAT]
duration=1200.981333
[/FORMAT]
  1. ffmpeg -threads 4 -i <視頻路徑> -ss <開(kāi)始時(shí)間點(diǎn)> -t <持續(xù)時(shí)間(s)> -c copy -y <輸出路徑>
    • -threads 4:多線程,感覺(jué)作用不是很大
    • <開(kāi)始時(shí)間點(diǎn)>:格式可以為hh:mm:ss,也可以為具體的視頻第幾秒
    • <持續(xù)時(shí)間(s)>:從指定的開(kāi)始時(shí)間點(diǎn)往后截取多少秒,不是結(jié)束時(shí)間點(diǎn)
    • -c copy:音視頻都直接復(fù)制,不重新編碼,速度快
    • -y:如果指定的輸出文件已經(jīng)存在,則覆蓋
    • 注意:如果輸出路徑在其他文件夾內(nèi),則必須提前創(chuàng)建好文件夾,比如輸出文件為./trimed_video/video.mp4,則需要提前創(chuàng)建好trimed_video文件夾,否則報(bào)錯(cuò)

python調(diào)用bash指令的方法

使用subprocess包,詳細(xì)信息可以自己查,簡(jiǎn)單用法如下:

import subprocess

command = "ffprobe -show_entries format=duration -v error -select_streams v:0 video.mp4"
result = subprocess.run(command, check=True,capture_output=True,text=True)
print(result.stdout) # 獲取命令執(zhí)行后的輸出數(shù)據(jù)

參數(shù)說(shuō)明:

  • command:要執(zhí)行的命令字符串,可以通過(guò)字符串操作來(lái)拼接需要的命令
  • check=True:如果進(jìn)程退出碼不為0,則拋出異常subprocess.CalledProcessError,可以通過(guò)try-catch進(jìn)行錯(cuò)誤處理
  • capture_output=True:捕獲標(biāo)準(zhǔn)輸出或標(biāo)準(zhǔn)錯(cuò)誤,獲取命令執(zhí)行的輸出信息
  • text=True:默認(rèn)標(biāo)準(zhǔn)輸出為字節(jié)類(lèi)型,這個(gè)可以改為字符串類(lèi)型,方便字符串解析

python處理代碼

注意,我所有代碼都沒(méi)考慮時(shí)長(zhǎng)超過(guò)1小時(shí)的視頻,如果需要操作1小時(shí)以上的視頻,請(qǐng)自行修改相關(guān)代碼

準(zhǔn)備函數(shù)

由于這兩個(gè)函數(shù)可能在多個(gè)文件中使用,因此單獨(dú)創(chuàng)建了一個(gè)文件,其他文件需要調(diào)用時(shí)通過(guò)import myfunc即可

"""myfunc.py"""
import os,re
from pathlib import Path
def match_files(dir,extension,content_range=[], not_content_range=[]):
    """在指定目錄下找符合擴(kuò)展名的文件,不遞歸

    用法示例:match_files("./",[".mp4", ".mkv"],range(74,80+1))
    
    extension:需要的擴(kuò)展名,字符串列表
    content_range:包含的范圍,為空則不限制,整數(shù)列表
    not_content_range:不包含的范圍,整數(shù)列表
    """
    matchs = []
    files = os.listdir(dir)
    for f in files:
        if Path(f).suffix in extension: # 檢查文件擴(kuò)展名是否在指定的擴(kuò)展名列表中
            # 提取文件名中的第一個(gè)數(shù)字序列作為編號(hào)
            number = int(re.findall(r'\d+',f)[0])
            if content_range:# 判斷是否指定了包含范圍,如果指定則判斷是否在范圍內(nèi)
                if number in content_range  and number not in not_content_range :
                    matchs.append(f)
            else: # 如果不指定范圍,則匹配所有
                if number not in not_content_range :
                    matchs.append(f)
    return matchs

def time_to_seconds(time_str):
    """將時(shí)間字符串轉(zhuǎn)換為秒,格式mm:ss"""
    minutes, seconds = map(int, time_str.split(':'))
    return  minutes * 60 + seconds

python批量處理

import myfunc
import subprocess
import re
"""
注意寫(xiě)好路徑,擴(kuò)展名,以及需要處理的序號(hào)范圍,排除的序號(hào)范圍
"""
videos = myfunc.match_files("./",[".mp4", ".mkv"],[140])
start_time_point = "02:35"
end_time_point = "17:42"
for video in videos:
    # 如果文件名有空格,需要加引號(hào)
    command1 = "ffprobe -show_entries format=duration -v error -select_streams v:0 \""+video+"\""
    try:
        # 先獲取視頻時(shí)長(zhǎng)
        result = subprocess.run(command1, check=True,capture_output=True,text=True)
        duration = round(float(re.search(r"duration=([\d.]+)",result.stdout).group(1)))
        """注意修改command2的參數(shù),
        00默認(rèn)小時(shí)為00,即不考慮時(shí)長(zhǎng)超過(guò)1小時(shí)的情況,按需修改
        "\"./trimed_video/"+video+"\""是輸出視頻路徑
        需要根據(jù)自己的視頻情況修改
        """
        command2 = "ffmpeg -threads 4 -i "+"\""+ video +"\""+ " -ss 00:" + start_time_point + " -t "+str(myfunc.time_to_seconds(end_time_point)-myfunc.time_to_seconds(start_time_point)) +" -c copy -y "+"\"./trimed_video/"+video+"\""
        try:
            # 運(yùn)行FFmpeg命令
            subprocess.run(command2, check=True,capture_output=True)
            print(f"視頻已成功裁剪到 {video}")
        except subprocess.CalledProcessError as e:
            print(f"FFmpeg命令執(zhí)行失敗: {e}", video)
    except subprocess.CalledProcessError as e:
        print(f"FFmpeg命令執(zhí)行失敗: {e}", video)

特殊情況處理

可能視頻的片頭和片尾時(shí)長(zhǎng)并不總是固定的,導(dǎo)致不能方便地按照 python批量處理的代碼,直接按相同的片頭長(zhǎng)度和片尾長(zhǎng)度操作,因此我使用了csv表格來(lái)記錄視頻的片頭片尾長(zhǎng)度,并使用python按照csv表格內(nèi)的數(shù)據(jù)裁剪視頻。

csv表格示例內(nèi)容如下片頭片尾信息.csv

???序號(hào),片頭時(shí)間點(diǎn)片尾時(shí)間點(diǎn),總時(shí)長(zhǎng)是必填項(xiàng),剩余兩項(xiàng)可以空著,但是必須填寫(xiě)英文分號(hào)。
其實(shí)總時(shí)長(zhǎng)可以通過(guò)ffmpeg命令獲取,但是既然是特殊情況,手動(dòng)打開(kāi)視頻了,填一下總時(shí)長(zhǎng)也不麻煩

可選操作:填補(bǔ)csv數(shù)據(jù)

有時(shí)候需要填寫(xiě)幾個(gè)視頻信息,來(lái)判斷這兩個(gè)序號(hào)之間的視頻是不是片頭片尾時(shí)長(zhǎng)一樣,如果一樣就可以通過(guò)python批量處理的代碼來(lái)操作,因此寫(xiě)了下面的代碼,可以自動(dòng)計(jì)算csv表格中的最后兩列數(shù)據(jù),觀察片頭時(shí)間點(diǎn)片尾長(zhǎng)度是否一直可以粗略判斷

import csv

# 文件路徑
file_path = "./片頭片尾信息.csv"
# 將時(shí)間字符串轉(zhuǎn)換為秒
def time_to_seconds(time_str):
    minutes, seconds = map(int, time_str.split(':'))
    return  minutes * 60 + seconds

# 讀取CSV文件
with open(file_path, mode='r', encoding='utf-8') as file:
    reader = csv.reader(file)
    rows = list(reader)

rows = [row for row in rows if row]
for i in range(1, len(rows)):
    end_time_str = rows[i][2]
    if rows[i][4]  != '':
        continue # 如果已經(jīng)有值了,則不再計(jì)算
    total_duration_str = rows[i][3]
    end_time_seconds = time_to_seconds(end_time_str)
    total_duration_seconds = time_to_seconds(total_duration_str)
    tail_length_seconds = total_duration_seconds - end_time_seconds
    rows[i][4] = str(tail_length_seconds)
    start_time_seconds = time_to_seconds(rows[i][1])
    rows[i][5] = str(end_time_seconds - start_time_seconds)

# 將更新后的內(nèi)容寫(xiě)回CSV文件
with open(file_path, mode='w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    writer.writerows(rows)

python根據(jù)csv數(shù)據(jù)裁剪視頻

import csv

# 文件路徑
file_path = "./片頭片尾信息.csv"
# 將時(shí)間字符串轉(zhuǎn)換為秒
def time_to_seconds(time_str):
    minutes, seconds = map(int, time_str.split(':'))
    return  minutes * 60 + seconds

# 讀取CSV文件
with open(file_path, mode='r', encoding='utf-8') as file:
    reader = csv.reader(file)
    rows = list(reader)

rows = [row for row in rows if row]
for i in range(1, len(rows)):
    end_time_str = rows[i][2]
    if rows[i][4]  != '':
        continue # 如果已經(jīng)有值了,則不再計(jì)算
    total_duration_str = rows[i][3]
    end_time_seconds = time_to_seconds(end_time_str)
    total_duration_seconds = time_to_seconds(total_duration_str)
    tail_length_seconds = total_duration_seconds - end_time_seconds
    rows[i][4] = str(tail_length_seconds)
    start_time_seconds = time_to_seconds(rows[i][1])
    rows[i][5] = str(end_time_seconds - start_time_seconds)

# 將更新后的內(nèi)容寫(xiě)回CSV文件
with open(file_path, mode='w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    writer.writerows(rows)

python根據(jù)csv數(shù)據(jù)裁剪視頻

import myfunc
import csv, re,subprocess
"""注意修改你想要匹配的文件擴(kuò)展名"""
videos = myfunc.match_files("./",[".mp4", ".mkv"])
"""注意改成你的csv文件路徑"""
with open("./片頭片尾信息.csv", mode='r', encoding='utf-8') as file:
    reader = csv.reader(file)
    rows = list(reader)

# 提取第一列數(shù)據(jù)
del rows[0]# 刪除表頭
first_column = [int(row[0]) for row in rows if row]  # 使用列表推導(dǎo)式,跳過(guò)空行
videos = [video for video in videos if int(re.findall(r'\d+',video)[0]) in first_column]

count = 0
for video in videos:
    command1 = "ffprobe -show_entries format=duration -v error -select_streams v:0 \""+video+"\""
    try:
        # 先獲取視頻時(shí)長(zhǎng)
        result = subprocess.run(command1, check=True,capture_output=True,text=True)
        duration = round(float(re.search(r"duration=([\d.]+)",result.stdout).group(1)))
        start_time_pint = myfunc.time_to_seconds(rows[count][1])
        end_time_pount = myfunc.time_to_seconds(rows[count][2])
        """注意替換你想要的輸出路徑"""
        command2 = "ffmpeg -threads 4 -i "+video + " -ss " + str(start_time_pint) + " -t "+str(end_time_pount-start_time_pint) +" -c copy -y "+"\"./trimed_video/"+video+"\""
        # print(command2)
        try:
            # 運(yùn)行FFmpeg命令
            subprocess.run(command2, check=True,capture_output=True)
            print(f"視頻已成功裁剪到 {video}")
        except subprocess.CalledProcessError as e:
            print(f"FFmpeg命令執(zhí)行失敗: {e}", video)
    except subprocess.CalledProcessError as e:
        print(f"FFmpeg命令執(zhí)行失敗: {e}", video)
    count += 1

視頻具有多個(gè)片段的處理 [TODO]

TODO有大佬知道的話歡迎討論,我覺(jué)得先切片再合并太麻煩。
這種特殊情況一般出現(xiàn)在,視頻有彩蛋之類(lèi)的,在片頭之前或片尾之后仍有正片內(nèi)容。

網(wǎng)上搜了但沒(méi)找到特別好的,找到一個(gè)文章但測(cè)試后不好用,所以選擇了手動(dòng)切片再合并,
多個(gè)視頻合并的ffmpeg命令:

  1. 創(chuàng)建文本文件filelist.txt,并寫(xiě)入要合并的多個(gè)視頻片段
file 'input1.mp4' 
file 'input2.mp4'
  • 執(zhí)行合并命令:ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4由于這種情況比較少,懶得寫(xiě)python代碼,自己手動(dòng)在cmd執(zhí)行吧

以上就是Python調(diào)用ffmpeg截取視頻片段并進(jìn)行批量處理方法的詳細(xì)內(nèi)容,更多關(guān)于Python ffmpeg截取視頻批量處理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解Python中的文件操作

    詳解Python中的文件操作

    在日常生活中,文件操作主要包括打開(kāi)、關(guān)閉、讀、寫(xiě)等操作,這篇文章主要為大家詳細(xì)介紹了Python中這些文件操作的實(shí)現(xiàn),需要的可以了解下
    2023-07-07
  • OpenCV中圖像與視頻的基礎(chǔ)操作總結(jié)

    OpenCV中圖像與視頻的基礎(chǔ)操作總結(jié)

    在計(jì)算機(jī)視覺(jué)領(lǐng)域,OpenCV是一款廣泛使用的開(kāi)源庫(kù),本文為大家介紹了如何使用OpenCV進(jìn)行這些操作,希望能幫助你更好地掌握?qǐng)D像處理和視覺(jué)任務(wù)的開(kāi)發(fā)技巧
    2023-06-06
  • Python中8種運(yùn)算符介紹以及示例

    Python中8種運(yùn)算符介紹以及示例

    在Python編程中運(yùn)算符是用于執(zhí)行各種操作的特殊符號(hào)或關(guān)鍵字,下面這篇文章主要給大家介紹了關(guān)于Python中8種運(yùn)算符介紹以及示例的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • Python中pickle模塊的使用詳解

    Python中pickle模塊的使用詳解

    這篇文章主要介紹了Python中pickle模塊的使用詳解,python的pickle模塊提供了一個(gè)簡(jiǎn)答的持久化功能,可以將對(duì)象以文件的形式存放在磁盤(pán)上,pickle模塊實(shí)現(xiàn)了基本的數(shù)據(jù)序列化和反序列化,需要的朋友可以參考下
    2023-08-08
  • Numpy實(shí)現(xiàn)按指定維度拼接兩個(gè)數(shù)組的實(shí)現(xiàn)示例

    Numpy實(shí)現(xiàn)按指定維度拼接兩個(gè)數(shù)組的實(shí)現(xiàn)示例

    Numpy提供了多個(gè)函數(shù)來(lái)拼接數(shù)組,其中最常用的是np.concatenate、np.vstack、np.hstack等,本文就來(lái)介紹一下Numpy實(shí)現(xiàn)按指定維度拼接兩個(gè)數(shù)組的實(shí)現(xiàn),感興趣的可以了解一下
    2024-03-03
  • Python?提速器numba

    Python?提速器numba

    這篇文章主要介紹了Python?提速器numba,相信大部分人都感嘆過(guò)python 真的太好用了,但是它真的好慢啊,然而今天我們就來(lái)用numba解決Python?慢的這個(gè)問(wèn)題,需要的朋友可以參考一下
    2022-01-01
  • ipad上運(yùn)行python的方法步驟

    ipad上運(yùn)行python的方法步驟

    在本篇文章里小編給大家分享的是關(guān)于ipad上運(yùn)行python的方法步驟以及相關(guān)知識(shí)點(diǎn),有需要的朋友們學(xué)習(xí)下。
    2019-10-10
  • python 實(shí)現(xiàn)一個(gè)圖形界面的匯率計(jì)算器

    python 實(shí)現(xiàn)一個(gè)圖形界面的匯率計(jì)算器

    這篇文章主要介紹了python 實(shí)現(xiàn)一個(gè)圖形界面的匯率計(jì)算器,幫助大家更好的理解和學(xué)習(xí)如何制作gui程序,感興趣的朋友可以了解下
    2020-11-11
  • Pycharm技巧之代碼跳轉(zhuǎn)該如何回退

    Pycharm技巧之代碼跳轉(zhuǎn)該如何回退

    用Pycharm寫(xiě)Python代碼有一段時(shí)間了,最近發(fā)現(xiàn)了一個(gè)Pycharm的一個(gè)小技巧想分享給大家,下面這篇文章主要給大家介紹了關(guān)于Pycharm代碼跳轉(zhuǎn)該如何回退的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-07-07
  • python兩種獲取剪貼板內(nèi)容的方法

    python兩種獲取剪貼板內(nèi)容的方法

    這篇文章主要介紹了python兩種獲取剪貼板內(nèi)容的方法,幫助大家更好的理解和使用python,完成需求,感興趣的朋友可以了解下
    2020-11-11

最新評(píng)論