天天看點

用python實作PR對視訊處理的基本操作

現在這個社會,視訊已經作為主要的資訊傳遞的媒介,越來越多的公司需要大量的視訊作為素材,那麼這些素材如何進行批量化非人工化生成尤為關鍵,在這個大背景下,我也盤點了當下使用頻率較高的視訊處理操作,并封裝成單獨的函數分享出來。建議收藏,代碼如下,提前安裝moviepy1.0.0版本即可。

import os
from moviepy.editor import *


# todo 視訊格式轉換
def formatchange(path_in, path_out):
    """
    将mov、avi等視訊格式轉換為🟟mp4格式
    :param path_in: 輸入路徑
    :param path_out: 輸出路徑
    :return: 無傳回值
    """

    cmd = 'ffmpeg -i ' + path_in + ' -strict -2 -vcodec h264 ' + path_out
    # 執行cmd指令
    os.system(cmd)


# todo 幀率設定
def setfps(inputvideo, fps):
    """
    設定視訊幀數
    :param inputvideo:
    :param fps: 幀數,例如25
    :return:
    """
    path, _ = os.path.splitext(inputvideo)
    a = '幀數設定{}.mp4'.format(fps)
    name = path + a
    cmd = 'ffmpeg -i ' + inputvideo + ' -r ' + str(fps) + ' ' + name
    # 執行cmd指令
    os.system(cmd)


# todo 比特率設定
def setbitrate(inputvideo, bitrate):
    """
    改變視訊碼率,降低碼率也可以實作對視訊大小的最優化壓縮
    :param inputvideo:
    :param bitrate: 例如600k
    :return:
    """
    path, _ = os.path.splitext(inputvideo)
    a = '設定碼率{}.mp4'.format(bitrate)
    name = path + a
    cmd = 'ffmpeg -i ' + inputvideo + ' -b:v ' + str(bitrate) + 'k ' + name
    # 執行cmd指令
    os.system(cmd)


# todo 剪掉片頭
def cutbegin(inputvideo, time):
    """
    剪切視訊片頭
    :param inputvideo: 輸入視訊目錄
    :param time: 片頭時長
    :return: 無傳回值
    """
    clip1 = VideoFileClip(inputvideo)  # 讀取視訊對象
    path, _ = os.path.splitext(inputvideo)
    mp3 = path + '.mp3'  # 構造🟟mp3儲存路徑
    outmp3 = path + 'out.mp3'
    end = clip1.duration  # 視訊時間總長
    shenyin = clip1.audio
    outname = path + '-剪切片頭.mp4'
    if shenyin != None:
        # 如果源視訊有聲音
        shenyin.write_audiofile(mp3)  # 提取儲存視訊音頻

        os.system(
            "ffmpeg -i {in_path} -vn -acodec copy -ss {Start_time} -t {Dur_time}  {out_path}".format(in_path=mp3,
                                                                                                     out_path=outmp3,
                                                                                                     Start_time=time,
                                                                                                     Dur_time=end))
        if time <= end:
            clip1 = clip1.cutout(0, time)  # 切除片頭
            clip1 = clip1.without_audio()  # 去除音頻
            name = path + 'cut.mp4'  # 構造名字
            clip1.write_videofile(name, audio=False)  # 儲存沒有音頻的視訊
            clip1.close()

            cmd = 'ffmpeg -i ' + name + ' -i ' + outmp3 + ' -strict -2 -f mp4 ' + outname
            # 執行cmd指令
            os.system(cmd)

            # 删除中間生成的多餘檔案
            os.remove(mp3)
            os.remove(outmp3)
            os.remove(name)
    else:
        # 如果原視訊沒有聲音
        if time <= end:
            clip1 = clip1.cutout(0, time)  # 切除片頭
            clip1.write_videofile(outname, audio=False)  # 儲存沒有音頻的視訊
            clip1.close()


# todo 剪掉片尾
def cutend(inputvideo, time):
    """
    剪切視訊片尾
    :param inputvideo: 輸入視訊目錄
    :param time: 片尾時間節點
    :return: 無傳回值
    """
    clip1 = VideoFileClip(inputvideo)  # 讀取視訊對象
    path, _ = os.path.splitext(inputvideo)
    mp3 = path + '.mp3'  # 構造🟟mp3儲存路徑
    outmp3 = path + 'out.mp3'
    end = clip1.duration  # 視訊時間總長
    shenyin = clip1.audio
    outname = path + '-剪切片尾.mp4'
    if shenyin != None:
        # 如果源視訊有聲音
        shenyin.write_audiofile(mp3)  # 提取儲存視訊音頻

        os.system(
            "ffmpeg -i {in_path} -vn -acodec copy -ss {Start_time} -t {Dur_time}  {out_path}".format(in_path=mp3,
                                                                                                     out_path=outmp3,
                                                                                                     Start_time=0,
                                                                                                     Dur_time=time))
        if time <= end:
            clip1 = clip1.cutout(time, end)  # 切除片尾
            clip1 = clip1.without_audio()  # 去除音頻
            name = path + 'cut.mp4'  # 構造名字
            clip1.write_videofile(name, audio=False)  # 儲存沒有音頻的視訊
            clip1.close()

            cmd = 'ffmpeg -i ' + name + ' -i ' + outmp3 + ' -strict -2 -f mp4 ' + outname
            # 執行cmd指令
            os.system(cmd)

            # 删除中間生成的多餘檔案
            os.remove(mp3)
            os.remove(outmp3)
            os.remove(name)
    else:
        # 如果原視訊沒有聲音
        if time <= end:
            clip1 = clip1.cutout(0, time)  # 切除片頭
            clip1.write_videofile(outname, audio=False)  # 儲存沒有音頻的視訊
            clip1.close()


# todo 視訊裁剪
def star_subclip_end(inputvideo, startime, endtime):
    """
    剪切自己感興趣的部分視訊片段
    :param inputvideo: 輸入視訊目錄
    :param startime: 剪輯開始時間節點
    :param endtime: 剪輯結束時間節點
    :return: 無傳回值
    """
    clip1 = VideoFileClip(inputvideo)  # 讀取視訊對象
    path, _ = os.path.splitext(inputvideo)
    mp3 = path + '.mp3'  # 構造🟟mp3儲存路徑
    outmp3 = path + 'out.mp3'
    end = clip1.duration  # 視訊時間總長
    shenyin = clip1.audio
    outname = path + '-視訊剪輯.mp4'
    if shenyin != None:
        # 如果源視訊有聲音
        shenyin.write_audiofile(mp3)  # 提取儲存視訊音頻

        os.system(
            "ffmpeg -i {in_path} -vn -acodec copy -ss {Start_time} -t {Dur_time}  {out_path}".format(in_path=mp3,
                                                                                                     out_path=outmp3,
                                                                                                     Start_time=startime,
                                                                                                     Dur_time=endtime))
        if endtime <= end:
            clip1 = clip1.subclip(startime, endtime)  # 視訊剪輯
            clip1 = clip1.without_audio()  # 去除音頻
            name = path + 'cut.mp4'  # 構造名字
            clip1.write_videofile(name, audio=False)  # 儲存沒有音頻的視訊
            clip1.close()

            cmd = 'ffmpeg -i ' + name + ' -i ' + outmp3 + ' -strict -2 -f mp4 ' + outname
            # 執行cmd指令
            os.system(cmd)

            # 删除中間生成的多餘檔案
            os.remove(mp3)
            os.remove(outmp3)
            os.remove(name)
    else:
        # 如果原視訊沒有聲音
        if endtime <= end:
            clip1 = clip1.subclip(startime, endtime)  # 視訊剪輯
            clip1.write_videofile(outname, audio=False)  # 儲存沒有音頻的視訊
            clip1.close()


# todo 視訊旋轉
def rotation(inputvideo, rota):
    """
    将視訊旋轉rota度
    :param inputvideo:
    :param rota:
    :return:
    """
    video1 = VideoFileClip(inputvideo)
    video1 = video1.rotate(rota)
    path, _ = os.path.splitext(inputvideo)
    a = '視訊旋轉{}度.mp4'.format(rota)
    name = path + a
    video1.write_videofile(name)


# todo 視訊鏡像
def mirror(inputvideo, model):
    """
    視訊鏡像
    :param inputvideo:
    :param model: model為1表示水準鏡像,為2表示垂直鏡像
    :return:
    """
    video1 = VideoFileClip(inputvideo)
    path, _ = os.path.splitext(inputvideo)
    if model == 1:  # 表示水準鏡像
        name = path + '水準鏡像.mp4'
        (video1.fx(vfx.mirror_x).write_videofile(name, codec='libx264'))
    elif model == 2:  # 表示垂直鏡像
        name = path + '垂直鏡像.mp4'
        (video1.fx(vfx.mirror_y).write_videofile(name, codec='libx264'))


# todo 視訊縮放
def setsize(inputvideo, w_size, h_size):
    """
    視訊按尺寸進行縮放,等比例縮小相當于下調分辨率
    :param inputvideo:
    :param w_size: 視訊寬度
    :param h_size: 視訊高度
    :return:
    """
    ship = VideoFileClip(inputvideo)
    clip = ship.resize([w_size, h_size])
    path, _ = os.path.splitext(inputvideo)
    a = '視訊縮放為{}x{}.mp4'.format(w_size, h_size)
    name = path + a
    clip.write_videofile(name)


# todo 調整視訊分辨率
def setresolution(inputvideo, w_size, h_size):
    """
    調整視訊分辨率
    :param inputvideo:
    :param w_size: 目标視訊寬度
    :param h_size: 目标視訊高度
    :return:
    """
    path, _ = os.path.splitext(inputvideo)
    a = '調整分辨率{}x{}.mp4'.format(w_size, h_size)
    name = path + a
    cmd = 'ffmpeg -i ' + inputvideo + ' -s ' + str(w_size) + 'x' + str(h_size) + ' ' + name
    # 執行cmd指令
    os.system(cmd)


# todo 視訊壓縮
def setbitrate(inputvideo, bitrate):
    """
    改變視訊碼率,降低碼率也可以實作對視訊大小的最優化壓縮
    :param inputvideo:
    :param bitrate: 例如600k
    :return:
    """
    path, _ = os.path.splitext(inputvideo)
    a = '設定碼率{}.mp4'.format(bitrate)
    name = path + a
    cmd = 'ffmpeg -i ' + inputvideo + ' -b:v ' + str(bitrate) + 'k ' + name
    # 執行cmd指令
    os.system(cmd)


# todo 添加文字水印

# todo 添加跑馬燈文字水印

# todo 畫中畫

# todo 添加背景音樂
def addmp3(inputvideo, mp3path):
    """
    給視訊增加音頻
    :param inputvideo: 輸入視訊目錄
    :param mp3path: 輸入音頻目錄
    :return:
    """
    path, _ = os.path.splitext(inputvideo)
    a = '增加音頻{}.mp4'.format(mp3path)
    outname = path + a
    cmd = 'ffmpeg -i ' + inputvideo + ' -i ' + mp3path + ' -strict -2 -f mp4 ' + outname
    os.system(cmd)


# todo 倍速播放
def speedplay(inputvideo, speed):
    """
    倍速播放
    :param inputvideo:
    :param speed: 速度,例如1.5
    :return:
    """

    path, _ = os.path.splitext(inputvideo)
    a = '改變速度{}.mp4'.format(speed)
    outname = path + a
    video = VideoFileClip(inputvideo)
    result = video.fl_time(lambda t: speed * t,
                           apply_to=['mask', 'video', 'audio']).set_end(video.end / speed)
    result.write_videofile(outname)


# todo 添加片頭
def addstarvideo(inputvideo, starvideo):
    """
    添加片頭
    :param inputvideo:
    :param starvideo:
    :return:
    """
    path, _ = os.path.splitext(inputvideo)
    a = '增加片頭{}.mp4'.format(starvideo)
    outname = path + a
    video1 = VideoFileClip(starvideo)
    video2 = VideoFileClip(inputvideo)
    video3 = concatenate_videoclips([video1, video2])
    video3.write_videofile(outname)


# todo 添加片尾
def addendvideo(inputvideo, endvideo):
    """
    添加片尾
    :param inputvideo:
    :param endvideo:
    :return:
    """
    path, _ = os.path.splitext(inputvideo)
    a = '增加片尾{}.mp4'.format(endvideo)
    outname = path + a
    video1 = VideoFileClip(inputvideo)
    video2 = VideoFileClip(endvideo)
    video3 = concatenate_videoclips([video1, video2])
    video3.write_videofile(outname)


# todo 視訊分段,具體根視訊的裁剪一個道理,加上一個業務邏輯就變成視訊分段了

# todo 視訊合成
def comvideo(inputvideo, endvideo):
    """
    視訊合成
    :param inputvideo:合成的第一段視訊
    :param endvideo:合成的第二段視訊
    :return:
    """
    path, _ = os.path.splitext(inputvideo)
    a = '視訊空間合成{}.mp4'.format(endvideo)
    outname = path + a
    video1 = VideoFileClip(inputvideo)
    video2 = VideoFileClip(endvideo)
    video3 = CompositeVideoClip([video1, video2])
    video3.write_videofile(outname)

# todo 自動生成電影混剪