python視頻轉碼腳本

今天有一個臨時的需求,就是需要將一個wmv的初步轉碼成mp4的格式。找了一圈,免費的工具少,即使有免費的工具,在功能上也是有所限制,或者會給你塞廣告或者附帶安裝其它流氓小游戲或者殺毒程序。

我并非不支持正版,我本人不是專業的視頻創作者,平日里對視頻轉碼編輯的需求極少,為這臨時需要而買個正常軟件,一沒必要,二不劃算。

FFmpeg 是一個強大的開源視頻工具包,通過命令行可以輕易的將一個 wmv 文件轉碼成需要的目標格式文件,例如轉碼成mp4

Python 也是個很好用的腳本語言。為可以快速的搜索視頻文檔,然后對其進行轉碼操作,使用Python寫了一個簡單的腳本,該腳本可以借助Everything的強大搜索功能,協助用戶快速的搜索定位需要轉碼的文檔,然后對其進行轉碼。

Python 腳本

Python腳本比較簡單,邏輯也比較清晰。截圖如下:

20240511141928

如👆上圖所示,腳本首先定義了一個命令行入參的類,用于管理和解析命令行傳入的參數。
然后定義了一個小的函數,這個函數并不是核心功能,僅用于對比兩個指定的字符串中的差異。

在主程序中(if __name__ == '__main__'部分),腳本首先解析了來自命令行的參數;
然后定義了一個Everything搜索接口對象(該Everything搜索接口對象提供了基于Everything的搜索功能),用于協助用戶快速的搜索定位興趣文檔。

在功能邏輯循環體中,首先引導用戶搜索定位待轉碼的視頻文檔;然后與用戶交互確定轉碼的目標格式;最后借助 moviepy這個Python包完成視頻轉碼操作。

以上,腳本邏輯清晰自然,貼出Python代碼如下👇。

# -*- coding:UTF-8 -*-
"""
@author: dyy
@contact: douyaoyuan@126.com
@time: 2024/5/10 21:40
@file: 視頻轉碼.py
@desc: xxxxxx
"""# region 引入必要的依賴
import os模塊名 = 'DebugInfo'
try:from DebugInfo.DebugInfo import *
except ImportError as impErr:print(f"嘗試導入 {模塊名} 依賴時檢測到異常:{impErr}")print(f"嘗試安裝 {模塊名} 模塊:")try:os.system(f"pip install {模塊名}")except OSError as osErr:print(f"嘗試安裝模塊 {模塊名} 時檢測到異常:{osErr}")exit(0)else:try:from DebugInfo.DebugInfo import *except ImportError as impErr:print(f"再次嘗試導入 {模塊名} 依賴時檢測到異常:{impErr}")exit(0)模塊名 = 'difflib'
try:import difflib  # 需要安裝 difflib 模塊,以支持字符差異對比操作
except ImportError as impErr:print(f"嘗試導入 {模塊名} 依賴時檢測到異常:{impErr}")print(f"嘗試安裝 {模塊名} 模塊:")try:os.system(f"pip install {模塊名}")except OSError as osErr:print(f"嘗試安裝模塊 {模塊名} 時檢測到異常:{osErr}")exit(0)else:try:import difflibexcept ImportError as impErr:print(f"再次嘗試導入 {模塊名} 依賴時檢測到異常:{impErr}")exit(0)模塊名 = 'moviepy'
try:from moviepy.editor import VideoFileClip  # 需要引入 moviepy 模塊,以支持視頻轉碼的操作
except ImportError as impErr:print(f"嘗試導入 {模塊名} 依賴時檢測到異常:{impErr}")print(f"嘗試安裝 {模塊名} 模塊:")try:os.system(f"pip install {模塊名}")except OSError as osErr:print(f"嘗試安裝模塊 {模塊名} 時檢測到異常:{osErr}")exit(0)else:try:from moviepy.editor import VideoFileClipexcept ImportError as impErr:print(f"再次嘗試導入 {模塊名} 依賴時檢測到異常:{impErr}")exit(0)
# endregion# 定義一個 命令行參數類,用于解析和記錄命令行參數
class 命令行參數類(入參基類):def __init__(self):super().__init__()self._添加參數('搜索關鍵字', str, '指定文檔搜索的關鍵字')self._添加參數('everything服務端口', str, 'everything HTTP 服務端口', '22')# region 訪問器@propertydef jsonCfg(self) -> str:if 'jsonCfg' in self._參數字典:return self._參數字典['jsonCfg'].else:return ''@jsonCfg.setterdef jsonCfg(self,: str):if 'jsonCfg' in self._參數字典:self._參數字典['jsonCfg'].= str()@propertydef 搜索關鍵字(self) -> str:if '搜索關鍵字' in self._參數字典:return self._參數字典['搜索關鍵字'].else:return ''@搜索關鍵字.setterdef 搜索關鍵字(self,: str):if '搜索關鍵字' in self._參數字典:self._參數字典['搜索關鍵字'].= str()@propertydef everything服務端口(self) -> str:if 'everything服務端口' in self._參數字典:return self._參數字典['everything服務端口'].else:return ''@everything服務端口.setterdef everything服務端口(self,: str):if 'everything服務端口' in self._參數字典:self._參數字典['everything服務端口'].= str()# endregion# 標注兩個字符串的差異項
def 差異標注(字串1: str, 字串2: str) -> tuple[str, str]:字串1 = str(字串1 if 字串1 else '').strip()字串2 = str(字串2 if 字串2 else '').strip()# region 原文檔變動對齊# 使用SequenceMatcher()類計算兩個字符串的相似度匹配器 = difflib.SequenceMatcher(None, 字串1, 字串2)差異 = 匹配器.get_opcodes()# 差異標注字串1差異標注: str = ''字串2差異標注: str = ''for opcode, i1, i2, j1, j2 in 差異:if opcode == 'equal':字串1差異標注 = 字串1差異標注 + 字串1[i1:i2]字串2差異標注 = 字串2差異標注 + 字串2[j1:j2]elif opcode == 'delete':字串1差異標注 = 字串1差異標注 + 紅字(字串1[i1:i2])elif opcode == 'insert':字串2差異標注 = 字串2差異標注 + 綠字(字串2[j1:j2])elif opcode == 'replace':字串1差異標注 = 字串1差異標注 + 紅字(字串1[i1:i2])字串2差異標注 = 字串2差異標注 + 綠字(字串2[j1:j2])return 字串1差異標注, 字串2差異標注if __name__ == '__main__':畫板 = 打印模板(False)畫板.執行位置(__file__)# region 解析入參入參 = 命令行參數類()入參.解析Json(畫板=畫板.副本.縮進())入參.解析入參(畫板=畫板.副本.縮進())if 畫板.正在調試:入參.展示(畫板=畫板.副本.縮進())搜索關鍵字: str = 入參.搜索關鍵字 if 入參.搜索關鍵字 else ''# endregion# region 定義搜索接口本地搜索: 搜索接口類 = 搜索接口類()if 在nt系統中():if 入參.everything服務端口:本地搜索.everything服務端口 = int(入參.everything服務端口)else:畫板.提示錯誤('入參.everything服務端口 參數無效')exit(1)# endregion# region 開始邏輯循環while True:def 文檔排除規則(文檔: str) -> bool:  # 排除一些不必要的干擾文檔if not 文檔:  # 空文檔不要return Trueif '\\recent\\' in 文檔.lower():  # recent 文檔夾內的文檔不要return Trueif 文檔.lower().endswith('.lnk'):  # *.lnk 文檔不要return True# region 引導用戶選擇需要轉碼的視頻文檔while True:原視頻文檔列表 = 交互接口類.指定選擇文檔(輸入提示='請輸入關鍵字以定位視頻文檔(0: 退出程序):',搜索接口=本地搜索,搜索關鍵字=搜索關鍵字,候選項上限=250,排除規則=文檔排除規則,多選=True,畫板=畫板.副本.縮進())if '0' in 原視頻文檔列表:# 用戶要求退出程序exit(0)if 原視頻文檔列表:畫板.消息('您選擇的文檔列出如下:')for 文檔 in 原視頻文檔列表:畫板.消息(綠字(文檔))break# endregion# region 目標格式信息交互目標視頻文檔列表: list[str] = []while True:目標格式后綴名: str = 交互接口類.發起文本交互(輸入提示='請輸入視頻目標格式(0: 退出程序):',畫板=畫板.副本.縮進())if '0' == 目標格式后綴名:# 用戶要求退出程序exit(0)if 目標格式后綴名.startswith('。'):目標格式后綴名 = f'.{目標格式后綴名[1:]}'if not 目標格式后綴名.startswith('.'):目標格式后綴名 = f'.{目標格式后綴名}'if not 目標格式后綴名.strip('.'):# 如果后綴名是空的,則重新要求輸入continue# 后綴名統一轉換成小寫格式目標格式后綴名 = 目標格式后綴名.lower()# 合成目標文檔名:for 文檔 in 原視頻文檔列表:目標視頻文檔列表.append(f'{文檔}{目標格式后綴名}')# 打的并提示用戶確認轉換方式畫板.消息(黃字('即將啟動的視頻轉碼如下:'))畫板.準備表格(對齊控制串='rl')for 序號 in range(len(原視頻文檔列表)):原文檔,目標文檔 = 差異標注(原視頻文檔列表[序號],目標視頻文檔列表[序號])畫板.添加一行(原文檔,洋紅字('->'),目標文檔)畫板.展示表格(列間距=[0,0])轉碼確認: str = 交互接口類.發起文本交互(輸入提示='是否確認轉碼?(y: 確認; n: 修改目標格式; 0: 退出程序)',限定范圍='YyNn0',畫板=畫板.副本.縮進())if '0' == 轉碼確認:# 用戶要求退出exit(0)elif 'y' == 轉碼確認.lower():# 用戶確認轉碼break# endregion# region 開始視頻轉碼編解碼格式: str = ''for 序號 in range(len(原視頻文檔列表)):視頻切片 = VideoFileClip(原視頻文檔列表[序號])while True:if not 編解碼格式:編解碼格式 = 交互接口類.發起文本交互(輸入提示=f'默認 codec 參數是 libx264, 輸入 {綠字("y")} 以確認; 'f'或者您可以輸入其它編碼格式({紅字("0")}: {紅字("退出程序")}):',畫板=畫板.副本.縮進())if '0' == 編解碼格式:# 用戶要求退出程序exit(0)編解碼格式 = 編解碼格式.lower()if 'y' == 編解碼格式:# 用戶確認使用 libx264 作為 codec 參數編解碼格式 = 'libx264'try:if 目標格式后綴名.endswith('gif'):視頻切片.write_gif(filename=目標視頻文檔列表[序號])elif 編解碼格式:視頻切片.write_videofile(filename=目標視頻文檔列表[序號], codec=編解碼格式)else:視頻切片.write_videofile(filename=目標視頻文檔列表[序號])except Exception as exp:畫板.提示錯誤('視頻轉碼遇到異常如下:')畫板.消息(exp.__str__())# 清除 codec 參數,重新發起交互編解碼格式 = ''continueelse:# 如果轉碼順利完成,則關閉 視頻切片,開始下一段視頻的處理視頻切片.close()break# endregion# endregion

使用演示

👉第一步,腳本首先引導用戶搜索和定位視頻文件,我們可以輸入視頻文件名信息以定位視頻文檔,然后參過序號選擇目標文檔;如下👇:
20240511144403

👉第二步,腳本詢問我們需要將視頻文檔轉換為什么樣的目標格式,我們輸入目標文檔的后綴名,然后再一次確認腳本的問詢;如下👇:
20240511144652
在這一步中,如果我們輸入了錯誤的目標格式,我們還可以輸入 n 來重新修改目標格式。

👉第三步,腳本會詢問我們是否使用默認的 codec 參數(默認為libx264)進行視頻轉碼,如果我們希望使用其它 codec 參數,例如 png,或者libvorbis 等,我們也可以直接輸入 codec 值來告訴腳本;如下👇:
Snipaste_2024-05-11_14-51-48
Snipaste_2024-05-11_14-51-52
以上👆腳本交互完成后,腳本即開始了視頻轉碼過程,我們耐心等待轉碼完成即可,如下👇:
20240511145705

懶人包

以上Python腳本的功能比較簡單,對于視頻轉碼的參數控制較少,但如果大家有需要,可以輕易的加入更多的轉碼參數控制功能。

以上 Python腳本,對應的bat調用腳本,和對應的cfg參數文檔,統一進行了打包,見:Python 視頻轉碼腳本。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/10539.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/10539.shtml
英文地址,請注明出處:http://en.pswp.cn/web/10539.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++面向對象學習筆記五

本文主要講解運算符重載,由于白鳯大佬沒有具體講解,所以本文自行補充了運算符重載的相關知識 目錄 文章目錄 前言 運算符重載 加號運算符重載 左移運算符重載 遞增運算符重載 總結 前言 本文主要對于運算符重載進行探討,分別對于成員函數重…

JVM 類加載機制

JVM 類加載機制分為五個部分:加載,驗證,準備,解析,初始化,下面我們就分別來看一下這五個過程。 加載 加載是類加載過程中的一個階段,這個階段會在內存中生成一個代表這個類的 java.lang.class 對…

C語言經典例題-9

1.簡單計算器 題目描述: KK實現一個簡單計算器,實現兩個數的“加減乘除”運算,用戶從鍵盤輸入算式“操作數1運算符操作數2”,計算并輸出表達式的值,如果輸入的運算符號不包括在(、-、*、/)范圍…

Navicat Premium安裝pojie版

下載、安裝mysql,環境變量配置 1、官網下載mysql:https://www.mysql.com/downloads/ 下載成功,進行安裝 一直點下一步 驗證,開始中搜索mysql 說明安裝成功 環境變量配置 默認安裝路徑C:\Program Files\MySQL …

向量檢索和關鍵字檢索的區別?

向量檢索(Vector Retrieval)和關鍵字檢索(Keyword Retrieval)是信息檢索領域中常見的兩種檢索方法,它們有一些顯著的區別: 1、檢索方式: 向量檢索:向量檢索是基于文檔和查詢之間的相…

Kafka和Spark Streaming的組合使用學習筆記(Spark 3.5.1)

一、安裝Kafka 1.執行以下命令完成Kafka的安裝: cd ~ //默認壓縮包放在根目錄 sudo tar -zxf kafka_2.12-2.6.0.tgz -C /usr/local cd /usr/local sudo mv kafka_2.12-2.6.0 kafka-2.6.0 sudo chown -R qiangzi ./kafka-2.6.0 二、啟動Kafaka 1.首先需要啟動K…

計算機畢業設計Python地震預測系統 地震數據分析可視化 地震爬蟲 大數據畢業設計 Flink Hadoop 深度學習 機器學習 人工智能 知識圖譜

學生信息 姓名:  祁浩 題目: 基于Python的中國地震數據分析與可視化系統的設計與實現 學號: 2020135211 班級: 20大數據本科2班 指導教師: 劉思思 答辯過程 學生開題陳述 為了讓學習者更好的了解了解地震…

Coze扣子開發指南:AI零代碼編程創建插件

在Coze扣子中創建插件,有兩種方式,一是用API,具體方式參照上一篇文章《Coze扣子開發指南:用免費API自己創建插件》,還有一種方式就是編程,不過有了AI的幫助,即使不會編程的人,也可以…

HarmonyOS開發案例:【生活健康app之獲取成就】(3)

獲取成就 本節將介紹成就頁面。 功能概述 成就頁面展示用戶可以獲取的所有勛章,當用戶滿足一定的條件時,將點亮本頁面對應的勛章,沒有得到的成就勛章處于熄滅狀態。共有六種勛章,當用戶連續完成任務打卡3天、7天、30天、50天、…

用大于meilisearch-java-0.7.0.jar的報錯的解決

Elasticsearch 做為老牌搜索引擎,功能基本滿足,但復雜,重量級,適合大數據量。 MeiliSearch 設計目標針對數據在 500GB 左右的搜索需求,極快,單文件,超輕量。 所以,對于中小型項目來說…

阿里云服務器在線安裝nginx

??個人主頁: 蒾酒 🔥系列專欄:《nginx實戰》 目錄 內容簡介 安裝步驟 1.root用戶登錄連接阿里云服務器 2.在usr/local下新建nginx目錄 3.安裝 1安裝下載工具 2下載nginx壓縮包 3解壓 4安裝nginx依賴的庫 5編譯并安裝 6啟動nginx 7開啟…

藍橋杯-遞增三元組(三種解法,二分, 雙指針, 前綴和)

給定三個整數數組 A[A1,A2,…AN], B[B1,B2,…BN], C[C1,C2,…CN], 請你統計有多少個三元組 (i,j,k) 滿足&#xff1a; 1≤i,j,k≤N Ai<Bj<Ck 輸入格式 第一行包含一個整數 N。 第二行包含 N 個整數 A1,A2,…AN。 第三行包含 N 個整數 B1,B2,…BN。 第四行包含 N …

【圖像畸變校正】

接上篇文章&#xff1a;【魚眼&#xff0b;普通相機】相機標定 附代碼&#xff1a; 方法一&#xff1a; 使用cv2.undistort """Create May 11, 2024author Wang Jiajun """import cv2 import numpy as npdef correct(img,camera_fileE:/cali…

怎么使用遠程桌面傳輸文件?

微軟提供的遠程桌面功能是一項強大的工具&#xff0c;可讓您在同一網絡下遠程訪問和管理其他計算機。除了遠程控制&#xff0c;它還支持文件傳輸功能&#xff0c;為Windows用戶提供了極大的便利。在接下來的內容中&#xff0c;我們將介紹如何使用遠程桌面傳輸文件。 如何從遠程…

PADS:生成自交叉平面區域

根據板外形鋪銅方法&#xff1a; pads根據板外形鋪銅_鋪銅如何根據板子形狀改變-CSDN博客 根據板外形創建平面區域出現問題&#xff1a; 解決方法&#xff1a;去找結構&#xff0c;讓他把出圖之前把線合并了

【數據結構】順序棧

順序棧 一、相關概念 棧和隊列是操作受限的線性表&#xff0c;是限定性的數據結構&#xff1b;棧分為順序棧和鏈式棧棧只能在一端進行操作&#xff08;插入、刪除&#xff09;棧是限定僅在表尾進行插入或刪除操作的線性表&#xff0c;因此&#xff0c;對棧來說&#xff0c;表…

https免費證書獲取

獲取免費證書的網址&#xff1a; Certbot 1. 進入你的linux系統&#xff0c;先安裝snapd&#xff0c; yum install snapd 2. 啟動snapd service snapd start 3.安裝 Certbot snap install --classic certbot 注意如下出現此錯誤時&#xff0c;需要先建立snap 軟連接后&am…

山東大學軟件學院創新項目實訓開發日志——第11周

山東大學軟件學院創新項目實訓開發日志——第11周 項目名稱&#xff1a;ModuFusion Visionary&#xff1a;實現跨模態文本與視覺的相關推薦 -------項目目標&#xff1a; 本項目旨在開發一款跨模態交互式應用&#xff0c;用戶可以上傳圖片或視頻&#xff0c;并使用文本、點、…

Golang | Leetcode Golang題解之第84題柱狀圖中最大的矩形

題目&#xff1a; 題解&#xff1a; func largestRectangleArea(heights []int) int {n : len(heights)left, right : make([]int, n), make([]int, n)for i : 0; i < n; i {right[i] n}mono_stack : []int{}for i : 0; i < n; i {for len(mono_stack) > 0 &&am…

SQLite索引名稱重復(index already exists)

文章目錄 概述報錯信息解決方案 概述 SQLite中創建單列索引的方式&#xff0c;跟MySQL類似&#xff1a; CREATE INDEX index_name ON table_name (column_name);但是也有不同的地方&#xff1a; MySQL中索引名稱在表內部不重復即可。 SQLite中索引名稱在整個庫中必須是不重復…