利用ffmpeg+Python實現(xiàn)MP4格式音頻與視頻的合并的方法-創(chuàng)新互聯(lián)

本篇文章給大家分享的是有關(guān)利用ffmpeg+Python實現(xiàn)MP4格式音頻與視頻的合并的方法,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

創(chuàng)新互聯(lián)10多年成都定制網(wǎng)站服務(wù);為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁設(shè)計及高端網(wǎng)站定制服務(wù),成都定制網(wǎng)站及推廣,對成都門簾等多個方面擁有多年的網(wǎng)站設(shè)計經(jīng)驗的網(wǎng)站建設(shè)公司。

環(huán)境變量

此電腦--屬性--高級系統(tǒng)設(shè)置--環(huán)境變量
在系統(tǒng)變量(也就是下面那一半)處找到新建,按如下所示的方法填寫

利用ffmpeg+Python實現(xiàn)MP4格式音頻與視頻的合并的方法

再將%FFMPEG_HOME%以及%FFMPEG_HOME%\bin寫入系統(tǒng)變量的Path中
然后一路確定即可

驗證

win+R,cmd
輸入ffmpeg -version

利用ffmpeg+Python實現(xiàn)MP4格式音頻與視頻的合并的方法

ffmpeg的使用

對于我將B站PC端緩存的音頻mp4和視頻mp4文件合并的需求,需要用到的命令為:
ffmpeg.exe -i audio1.mp4 -i video.mp4 -acodec copy -vcodec copy output.mp4
可以把mp4的文件設(shè)置成絕對路徑,這樣就可以轉(zhuǎn)換指定路徑的文件以及保存到指定路徑了,比如這樣:
ffmpeg.exe -i "E:\嗶哩嗶哩視頻\ss27993\77413703\1\audio1.mp4" -i "E:\嗶哩嗶哩視頻\ss27993\77413703\1\video.mp4" -acodec copy -vcodec copy "E:\B站導(dǎo)出視頻\Dr.STONE石紀(jì)元\第22話寶物.mp4
通過PC端緩存的未合并的視頻和音頻,全都是命名為video.mp4和audio.mp4
PS:有些兄弟是導(dǎo)出的手機端緩存的視頻和音頻,是m4s格式的,方法也一樣
但光有這條命令還不夠,需要自己手動一個個操作,太麻煩了
因此我還需要使用Python來自動幫我完成工作

Python實現(xiàn)自動處理

雖然Python可以實現(xiàn)自動化,減少時間的浪費,但最快的還是以后記得緩存時勾選自動合并

利用ffmpeg+Python實現(xiàn)MP4格式音頻與視頻的合并的方法

文件結(jié)構(gòu)

PC端緩存的視頻保存的文件結(jié)構(gòu)有很多種,我只是根據(jù)我碰到的情況寫的,但大同小異,修改起來也不麻煩,只是再加個if和else罷了

番劇緩存結(jié)構(gòu)

緩存的番劇是這種結(jié)構(gòu):

利用ffmpeg+Python實現(xiàn)MP4格式音頻與視頻的合并的方法
利用ffmpeg+Python實現(xiàn)MP4格式音頻與視頻的合并的方法
利用ffmpeg+Python實現(xiàn)MP4格式音頻與視頻的合并的方法

上面舉的例子是Dr.stone石紀(jì)元,我緩存的鬼滅之刃也是如此
特點是在一個以視頻ID號名稱的文件夾(ss27993)后,跟著許多子文件夾(57983089等),然后在這些子文件夾中又有一個或多個子文件夾(比如1),然后緩存的視頻保存在這個文件夾里,里面有一個info文件(就是json格式),還有audio1.mp4和video.mp4。
PS:
還有一個xml文件,是彈幕信息,暫時我不知道怎么處理

利用ffmpeg+Python實現(xiàn)MP4格式音頻與視頻的合并的方法

常規(guī)緩存結(jié)構(gòu)

除了番劇,一般的視頻緩存的結(jié)構(gòu)是這樣的

利用ffmpeg+Python實現(xiàn)MP4格式音頻與視頻的合并的方法
利用ffmpeg+Python實現(xiàn)MP4格式音頻與視頻的合并的方法

不難看出,這比番劇要少一個層級

文件信息

文件信息主要由info文件和dvi文件來記錄
這兩種文件都可以直接以json文件來處理,也就是,首先open函數(shù)打開文件,然后用json.load轉(zhuǎn)成字典。。。
然后我還發(fā)現(xiàn)了一個特點是,視頻和音頻所在的目錄下是info文件,而它的上一層目錄下是dvi文件
雖然文件格式基本是一致的,但是里面的鍵-值關(guān)系卻不一致,單集視頻的名稱在番劇中對應(yīng)的是鍵Description,在其他視頻中對應(yīng)的是PartName
視頻總的名稱保存在外層的目錄下的info文件或dvi文件中,番劇中對應(yīng)的鍵是SeasonTitle,在其他視頻中對應(yīng)的是Title

利用ffmpeg+Python實現(xiàn)MP4格式音頻與視頻的合并的方法

具體問題具體分析,首先由于我實踐得較少,這樣的總結(jié)不一定對,然后以后也許也會有新的格式、新的變化

代碼

具體代碼

以下是我的Python代碼,你可以先試試能不能用,用不了的話,可以在理解的基礎(chǔ)上修改。理解不了的話可以看我的后面的解釋,以及代碼中的注釋,對于運行過程中一些變量的值,我都把它放在注釋中了,方便你理解。

# -*- coding = utf-8 -*-
# @time:2020/10/17/017 23:09
# Author:cyx
# @File:main.py.py
# @Software:PyCharm

# 從.info文件中獲得了Title信息,但是如果其中有某些特殊字符,保存時可能出現(xiàn)問題
def get_correct_title(title):

  error_set = ['/', '\\', ':', '*', '&#63;', '"', '|', '<', '>', '\b', ' ', '.']
  correct_title = title
  # print(title)
  for c in correct_title:
    if c in error_set:
      correct_title = correct_title.replace(c, '')
  return correct_title

def popen(cmd):
  # https://blog.csdn.net/qq_41451161/article/details/82901235
  try:
    popen = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    popen.wait()
    lines = popen.stdout.readlines()
    return [line.decode('gbk') for line in lines]
  except BaseException as e:
    return -1

if __name__ == '__main__':
  import os
  import json
  import subprocess

  # ffmpeg -i video.m4s -i audio.m4s -c:v copy -c:a aac -strict experimental output.mp4
  # ffmpeg.exe -i audio1.mp4 -i video.mp4 -acodec copy -vcodec copy output.mp4
  AVhao = input("請輸入視頻AV號:")
  superPath = "E:\\嗶哩嗶哩視頻" + "\\" + AVhao
  partDirs = [] # 保存每P視頻所在的文件夾路徑
  paths = os.listdir(superPath) # 獲取當(dāng)前路徑下所有的文件(包括文件夾)名稱
  # paths = ['8','9']
  # 有時候,會莫名其妙的少了幾個視頻,可以通過重載來重新加載缺失的視頻
  # print(paths)
  # paths
  # ['27993.info', '57983089', '58612211', '59811008', '60862133', '61898240', '62925012', '64005445', '65020725', '66013155', '66808912', '67587875', '68398229', '69175748', '70021307', '70873680', '71617211', '73379440', '74051851', '74974157', '75746600', '76619409', '77413703', '78266594', '79070874', 'cover.jpg', 'desktop.ini']
  # 獲取每P視頻所在的文件夾路徑
  savePos = ''
  seq = []
  # 鑒于有些up主命名時毫無規(guī)律,導(dǎo)出后無法正常排序,只能手動排序了
  # 根據(jù)AV號名文件夾下的子文件夾的名稱進(jìn)行排序,但是番劇的話不是這樣排序,不過番劇單集的名稱很規(guī)范,不需要這樣
  for p in paths:
    if '.' not in p:
      seq.append(p)
    if 'info' in p:
      # print(p)
      # p:
      # 27993.info
      info = superPath + "\\" + p
      with open(info, 'r', encoding='utf-8') as load_f:
        load_dict = json.load(load_f)
        projectTitle = load_dict['SeasonTitle']
        projectTitle = get_correct_title(projectTitle)
        savePos = 'E:\\B站導(dǎo)出視頻\\' + projectTitle
        print('savePos: ', savePos)

    if 'dvi' in p:
      # print(p)
      # P:
      # 328738595.dvi
      dvi = superPath + "\\" + p
      with open(dvi, 'r', encoding='utf-8') as load_f:
        load_dict = json.load(load_f)
        projectTitle = load_dict['Title']
        projectTitle = get_correct_title(projectTitle)
        savePos = 'E:\\B站導(dǎo)出視頻\\' + projectTitle
        print('savePos: ', savePos)
    # 防止文件存在時再次生成該文件夾出現(xiàn)錯誤
    try:
      os.mkdir(savePos)
      break
    except:
      pass

    subDir = superPath + "\\" + p
    if os.path.isdir(subDir):
      # print(subDir)
      # 所有子文件夾的路徑保存在partDirs中
      partDirs.append(subDir)
  # print("partDirs: ",partDirs)
  # partDirs: ['E:\\嗶哩嗶哩視頻\\ss27993\\57983089', 'E:\\嗶哩嗶哩視頻\\ss27993\\58612211', 'E:\\嗶哩嗶哩視頻\\ss27993\\59811008', 'E:\\嗶哩嗶哩視頻\\ss27993\\60862133', 'E:\\嗶哩嗶哩視頻\\ss27993\\61898240', 'E:\\嗶哩嗶哩視頻\\ss27993\\62925012', 'E:\\嗶哩嗶哩視頻\\ss27993\\64005445', 'E:\\嗶哩嗶哩視頻\\ss27993\\65020725', 'E:\\嗶哩嗶哩視頻\\ss27993\\66013155', 'E:\\嗶哩嗶哩視頻\\ss27993\\66808912', 'E:\\嗶哩嗶哩視頻\\ss27993\\67587875', 'E:\\嗶哩嗶哩視頻\\ss27993\\68398229', 'E:\\嗶哩嗶哩視頻\\ss27993\\69175748', 'E:\\嗶哩嗶哩視頻\\ss27993\\70021307', 'E:\\嗶哩嗶哩視頻\\ss27993\\70873680', 'E:\\嗶哩嗶哩視頻\\ss27993\\71617211', 'E:\\嗶哩嗶哩視頻\\ss27993\\73379440', 'E:\\嗶哩嗶哩視頻\\ss27993\\74051851', 'E:\\嗶哩嗶哩視頻\\ss27993\\74974157', 'E:\\嗶哩嗶哩視頻\\ss27993\\75746600', 'E:\\嗶哩嗶哩視頻\\ss27993\\76619409', 'E:\\嗶哩嗶哩視頻\\ss27993\\77413703', 'E:\\嗶哩嗶哩視頻\\ss27993\\78266594', 'E:\\嗶哩嗶哩視頻\\ss27993\\79070874']
  videoPos = ''
  i = 0
  for p in partDirs:
    # print(p)
    # 列出子文件夾中的所有文件
    sublist = os.listdir(p)
    # 檢查info文件是否在當(dāng)前子文件夾中
    for file in sublist:
      # print(file)
      # file:
      # 1
      # 57983089.
      # dvi
      # cover.jpg
      # desktop.ini
      if 'info' in file:
        infoPos = p + "\\" + file
        videoPos = p
      else:
        subsubDir = p + "\\" + file
        if os.path.isdir(subsubDir):
          # print(subsubDir)
          # subsubDir: E:\嗶哩嗶哩視頻\ss27993\57983089\1
          subsubList = os.listdir(subsubDir)
          for subsubFile in subsubList:
            if 'info' in subsubFile:
              infoPos = subsubDir + "\\" + subsubFile
              videoPos = subsubDir
              break
      with open(infoPos, 'r', encoding='utf-8') as load_f:
        load_dict = json.load(load_f)
        if 'ss' in AVhao:
          videoTitle = load_dict['Description']
        else:
          videoTitle = load_dict['PartName']

        videoTitle = get_correct_title(videoTitle)
        print('videoTitle: ', videoTitle)
        videoDir = videoPos + "\\" + 'video.mp4'
        audioDir = videoPos + "\\" + 'audio1.mp4'
        # print('videoDir: ', videoDir)
        # print('audioDir: ', audioDir)
        # videoDir: E:\嗶哩嗶哩視頻\ss27993\74051851\1\video.mp4
        # audioDir: E:\嗶哩嗶哩視頻\ss27993\74051851\1\audio1.mp4
        if 'ss' in AVhao:
          outDir = savePos + "\\" + videoTitle + '.mp4'
        else:
          outDir = savePos + "\\" + seq[i] + '_' + videoTitle + '.mp4'
          i += 1
        # 對于那些命名很規(guī)范的視頻,可以不用自己再排序,進(jìn)行一下重載,不規(guī)范的視頻再把這句注釋掉就好
        outDir = savePos + "\\" + videoTitle + '.mp4'
        # command = 'cd ' + superPath + '\\64 && ' # && 多名命令
        # command = 'cd ' + 'E:\\ProgramFiles\\ffmpeg' + ' && '
        command = 'E:\\FFmpeg\\bin\\ffmpeg.exe -i ' + '"' + audioDir + '"' ' -i ' + '"' + videoDir + '"'+ ' -acodec copy -vcodec copy ' + '"' + outDir + '"'
        # print("保存地址",outDir)
        # 保存地址 E:\B站導(dǎo)出視頻\[Lynda視頻]音頻錄制錄音技巧教程(中英雙語字幕)全集130課時AudioRecordingTechniques混音錄音棚音樂工作室歌曲調(diào)音\98錄制獨奏薩克斯演奏技巧二.mp4
        # print(command)
        # command = 'E:\\FFmpeg\\bin\\ffmpeg.exe -i "E:\嗶哩嗶哩視頻\ss27993\77413703\1\audio1.mp4" -i "E:\嗶哩嗶哩視頻\ss27993\77413703\1\video.mp4" -acodec copy -vcodec copy "E:\B站導(dǎo)出視頻\Dr.STONE石紀(jì)元\第22話寶物.mp4'
        # os.system(command)
        popen(command)
        # ffmpeg.exe -i audio1.mp4 -i video.mp4 -acodec copy -vcodec copy output.mp4
        break

文章題目:利用ffmpeg+Python實現(xiàn)MP4格式音頻與視頻的合并的方法-創(chuàng)新互聯(lián)
網(wǎng)頁鏈接:http://muchs.cn/article38/eipsp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、商城網(wǎng)站、App開發(fā)虛擬主機、標(biāo)簽優(yōu)化Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司