1. 程式人生 > 程式設計 >用python進行視訊剪輯

用python進行視訊剪輯

一、目標

python,利用moviepy和pydub將一段視訊進行區間切割

二、原始碼

import os
from moviepy.video.io.VideoFileClip import VideoFileClip
from pydub import AudioSegment


def clip_video(source_file,target_file,start_time,stop_time):
  """
  利用moviepy進行視訊剪下
  :param source_file: 原視訊的路徑,mp4格式
  :param target_file: 生成的目標視訊路徑,mp4格式
  :param start_time: 剪下的起始時間點(第start_time秒)
  :param stop_time: 剪下的結束時間點(第stop_time秒)
  :return:
  """
  validate_file(source_file)
  source_video = VideoFileClip(source_file)
  video = source_video.subclip(int(start_time),int(stop_time)) # 執行剪下操作
  video.write_videofile(target_file) # 輸出檔案


def clip_audio(source_file,stop_time):
  """
  利用pydub進行音訊剪下。pydub支援原始檔為 mp4格式,因此這裡的輸入可以與視訊剪下原始檔一致
  :param source_file: 原視訊的路徑,mp4格式
  :param target_file: 生成的目標視訊路徑,mp4格式
  :param start_time: 剪下的起始時間點(第start_time秒)
  :param stop_time: 剪下的結束時間點(第stop_time秒)
  :return:
  """
  validate_file(source_file)
  audio = AudioSegment.from_file(source_file,"mp4")
  audio = audio[start_time * 1000: stop_time * 1000]
  audio_format = target_file[target_file.rindex(".") + 1:]
  audio.export(target_file,format=audio_format)


def combine_video_audio(video_file,audio_file,delete_tmp=False):
  """
  利用 ffmpeg將視訊和音訊進行合成
  :param video_file:
  :param audio_file:
  :param target_file:
  :param delete_tmp: 是否刪除剪下過程生成的原視訊/音訊檔案
  :return:
  """
  validate_file(video_file)
  validate_file(audio_file)
  # 注:需要先指定音訊再指定視訊,否則可能出現無聲音的情況
  command = "ffmpeg -y -i {0} -i {1} -vcodec copy -acodec copy {2}".format(audio_file,video_file,target_file)
  os.system(command)
  if delete_tmp:
    os.remove(video_file)
    os.remove(audio_file)


def clip_handle(source_file,stop_time,tmp_path=None,delete_tmp=False):
  """
  將一個視訊檔案按指定時間區間進行剪下
  :param source_file: 原視訊檔案
  :param target_file: 目標視訊檔案
  :param start_time: 剪下的起始時間點(第start_time秒)
  :param stop_time: 剪下的結束時間點(第stop_time秒)
  :param tmp_path: 剪下過程的檔案存放位置
  :param delete_tmp: 是否刪除剪下生成的檔案
  :return:
  """
  # 設定臨時檔名
  if tmp_path is None or not os.path.exists(tmp_path):
    # 如果沒有指定臨時檔案路徑,則預設與目標檔案的位置相同
    tmp_path = target_file[: target_file.rindex("/") + 1]
  target_file_name = target_file[target_file.rindex("/") + 1: target_file.rindex(".")]
  tmp_video = tmp_path + "v_" + target_file_name + ".mp4"
  tmp_audio = tmp_path + "a_" + target_file_name + ".mp4"

  # 執行檔案剪下及合成
  clip_video(source_file,tmp_video,stop_time)
  clip_audio(source_file,tmp_audio,stop_time)
  combine_video_audio(tmp_video,delete_tmp)


def validate_file(source_file):
  if not os.path.exists(source_file):
    raise FileNotFoundError("沒有找到該檔案:" + source_file)


def test_example():
  """
  測試例子
  :return:
  """
  root_path = 'XXX/videos/'
  video_name = "test.mp4"
  source_file = root_path + video_name
  start_time = 5
  stop_time = 6

  # 設定目標檔名
  target_name = str(start_time) + "_" + str(stop_time)
  target_file = root_path + "c_" + target_name + ".mp4"
  # 處理主函式
  clip_handle(source_file,stop_time)


if __name__ == "__main__":
  test_example()

三、遇到的問題

1. moviepy切割後的視訊沒有聲音

解決方案:通過pydub切割後再合併

2. 直接利用ffmpeg切割後,視訊會出現黑屏、時間區間不準確、解析度低

解決方案:用了各種命令也沒有成功,所以放棄。。。

3. 合併時,不支援mp3、 wav等格式

解決方案:統一儲存為mp4

以上就是用python進行視訊剪輯的詳細內容,更多關於python 視訊剪輯的資料請關注我們其它相關文章!