短視頻篇 | Python 帶你進(jìn)行短視頻二次創(chuàng)作

image

閱讀文本大概需要 10 分鐘。

1、目 標(biāo) 場 景

無論是抖音還是快手等視頻平臺(tái),一旦一個(gè)視頻火了后,很多 UP 主都會(huì)爭先搶后去模仿拍攝或剪輯,然后上傳到平臺(tái),最后都能帶來不錯(cuò)的流量。

對(duì)于一般的短視頻,完全可以通過裁剪、特效轉(zhuǎn)場、加入混合圖層和字幕等一系列操作,很快就能制作出一個(gè)全新的視頻,這些操作完全可以使用 Python 來實(shí)現(xiàn)。

image

本篇文章的目的是帶大家利用 Python 實(shí)現(xiàn)短視頻的二次創(chuàng)作。

2、編 寫 代 碼

要實(shí)現(xiàn)短視頻的二次創(chuàng)作,一般需要下面 7 個(gè)步驟,分別是:獲取原始視頻屬性數(shù)據(jù)、視頻幀處理、視頻區(qū)域裁剪、制作背景圖片視頻、合成多段視頻、生成描述字幕、加入字幕和背景音樂。

第 1 步,獲取原始視頻屬性數(shù)據(jù)

首先,利用 爬蟲 獲取無水印的原始視頻,Github 上有很多現(xiàn)成的輪子。

然后,實(shí)例化視頻片段 VideoFileClip,得到視頻的寬、高、幀率等基本屬性。

self.video_raw_clip = VideoFileClip(self.video_raw_path)

# 視頻寬、高
self.video_width, self.video_height = self.video_raw_clip.w, self.video_raw_clip.h

self.fps = self.video_raw_clip.fps

接著,分離出音頻文件,對(duì)原始視頻進(jìn)行一次剪輯,去除掉視頻平臺(tái)追加的公共畫面片段,重新生成一個(gè)視頻文件。

比如抖音默認(rèn)會(huì)追加 4s 的公共視頻片段。

  # 分離出音頻
self.audio = self.video_raw_clip.audio.subclip(0, self.video_raw_clip.duration - 4)

# 裁剪尾部的視頻素材
temp_video_clip = self.video_raw_clip.subclip(0, self.video_raw_clip.duration - 4)

# 生成新的視頻,并保存到本地
temp_video_clip.set_audio(self.audio)

video_path = './source/temp_source_video.mp4'

temp_video_clip.write_videofile(video_path, codec='libx264',
                                        audio_codec='aac',
                                        temp_audiofile='temp-audio.m4a',
                                        remove_temp=True)

第 2 步,視頻幀處理

要對(duì)一個(gè)視頻進(jìn)行畫面裁剪,首先知道開始裁剪的 起始坐標(biāo)點(diǎn)、裁剪的范圍。

image

使用 ffmpeg 命令拿到視頻某一個(gè)時(shí)間點(diǎn)的圖片幀,并保存圖片文件到本地。

def time_to_hms(seconds_time):
    """
    時(shí)間轉(zhuǎn)為時(shí)分秒
    :param seconds_time: 秒數(shù)
    :return:
    """
    m, s = divmod(seconds_time, 60)
    h, m = divmod(m, 60)
    return "%02d:%02d:%02d" % (h, m, s)

def get_frame_from_video(video_name, frame_time, img_path):
    """
    獲取視頻某個(gè)時(shí)間的幀圖片,保存在本地
    get_frame_from_video('./../source/source.mp4', 1, './22.jpg')
    :param video_name: 視頻路徑
    :param frame_time: 截取幀的時(shí)間位置(s)
    :param img_path:生成圖片的完整路徑
    :return:
    """
    # 秒轉(zhuǎn)為時(shí)、分、秒
    time_pre = time_to_hms(frame_time)

    os.system('ffmpeg -ss %s -i %s -frames:v 1 %s' % (time_pre, video_name, img_path))

接著利用 PS 的標(biāo)尺和選區(qū)工具配合信息對(duì)話框,獲取要裁剪的起始坐標(biāo)、裁剪寬高數(shù)據(jù)。

# 裁剪起始坐標(biāo)
position1 = (0, 328)

# 630 為要裁剪的高度
position2 = (self.video_width, 630)

第 3 步,視頻區(qū)域裁剪

moviepy 提供的 crop() 方法可以很方便的區(qū)域裁剪視頻。

需要注意的是,crop() 方法傳入的坐標(biāo)值必須是 偶數(shù),否則會(huì)導(dǎo)致區(qū)域裁剪失敗。

def video_crop(self, position1, position2, croped_video_path):
     """
     視頻裁剪
     :return:
     """

     # 裁剪的坐標(biāo),包含左上角x軸和y軸;右下角x軸和y軸
     clip2 = fx.all.crop(self.video_clip, x1=position1[0], y1=position1[1], x2=position2[0], y2=position2[1])

     # 保存文件
     clip2.write_videofile(croped_video_path)

     # 時(shí)長
     self.time = clip2.duration

     return clip2

第 4 步,制作背景圖片視頻

為了保證手機(jī)上的觀感,針對(duì)上面裁剪橫向視頻,需要混合加入一個(gè)豎屏的背景圖片圖層或視頻。

之前寫過一篇 利用圖片制作 GIF 視頻 的教程,這里實(shí)現(xiàn)方式類似,即一個(gè) 圖片幀循環(huán)寫入 到視頻文件中。

def one_pic_to_video(image_path, output_video_path, fps, time):
    """
    一張圖片合成視頻
    one_pic_to_video('./../source/1.jpeg', './../source/output.mp4', 25, 10)
    :param path: 圖片文件路徑
    :param output_video_path:合成視頻的路徑
    :param fps:幀率
    :param time:時(shí)長
    :return:
    """

    image_clip = ImageClip(image_path)
    img_width, img_height = image_clip.w, image_clip.h

    # 總共的幀數(shù)
    frame_num = (int)(fps * time)

    img_size = (int(img_width), int(img_height))

    fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')

    video = cv2.VideoWriter(output_video_path, fourcc, fps, img_size)

    for index in range(frame_num):
        frame = cv2.imread(image_path)
        # 直接縮放到指定大小
        frame_suitable = cv2.resize(frame, (img_size[0], img_size[1]), interpolation=cv2.INTER_CUBIC)

        # 把圖片寫進(jìn)視頻
        # 重復(fù)寫入多少次
        video.write(frame_suitable)

    # 釋放資源
    video.release()

    return VideoFileClip(output_video_path)

需要注意的是,合成圖片視頻的 幀率、時(shí)長 要和上一段視頻保持一致。

第 5 步,合成兩段視頻

上面 2 步完成了原始視頻的區(qū)域裁剪和背景視頻的制作,現(xiàn)在可以將這兩段視頻進(jìn)行一次合成。

由于兩段視頻的寬度很有可能不一樣,為了保證合成視頻的統(tǒng)一性,需要對(duì)其中一段視頻的長寬進(jìn)行 等比例縮放,使得兩段視頻的寬度保證一致。

def synthetic_video(video1_clip, video2_clip2):
    """
    合成兩段視頻,生成視頻的寬高以第一段視頻為準(zhǔn)
    :param video1_clip:
    :param video2_clip2:
    :return:
    """
    # 最后生成視頻的寬、高
    width, height = video1_clip.w, video1_clip.h

    # 第二段視頻的實(shí)際寬、高
    video_width, video_height = video2_clip2.w, video2_clip2.h

    # 最第二段視頻進(jìn)行縮放
    video_clip1 = video2_clip2.resize((width, width * video_height / video_width))

    # 合成視頻的路徑
    synthetic_video_clip = CompositeVideoClip([video1_clip, video_clip1.set_pos("center")])

    synthetic_video_clip.write_videofile(
        './source/temp_synthetic_video.mp4')

    return synthetic_video_clip

第 6 步,生成描述字幕

使用 TextClip 可以生成一個(gè)描述信息,文字信息屬性包含字體名稱、大小、顏色、位置、開始時(shí)間及持續(xù)時(shí)間都可以一起設(shè)置進(jìn)去。

# 描述字幕
TextClip(text_content, font='./fonts/STHeiti Medium.ttc',
                    fontsize=font_params.get('size'), kerning=font_params.get('kerning'),
                    color=font_params.get('color')).set_position(("center", 150)).set_duration(duration)

默認(rèn)字體可能會(huì)導(dǎo)致中文字幕不顯示,因此,最好指定特定的中文字體。

第 7 步,加入字幕和背景音樂

使用 CompositeVideoClip 即可以將字幕片段嵌入到視頻片段中,然后利用 set_audio 把音頻文件為視頻增加一條音頻軌道。

最后寫入到文件中,即可以生成一個(gè)新的短視頻。

# 加入字幕
video_with_text_clip = CompositeVideoClip([synthetic_video_clip, desc_text_clip.set_start(0)])

# 設(shè)置背景音樂
video_with_text_clip.set_audio(self.audio).write_videofile("output.mp4",
                                                                   codec='libx264',
                                                                   audio_codec='aac',
                                                                   temp_audiofile='temp-audio.m4a',
                                                                   remove_temp=True
                                                                   )
# 刪除所有的臨時(shí)文件
del_temp_file("./source/")

3、結(jié) 果 結(jié) 論

通過上面的 7 步操作,就能完成對(duì)大部分短視頻的二次創(chuàng)作。

我已經(jīng)將全部源碼上傳到公眾號(hào)后臺(tái),關(guān)注公眾號(hào)「 AirPython 」,后臺(tái)回復(fù)「 二次創(chuàng)作 」即可獲得全部源碼。

如果你覺得文章還不錯(cuò),請(qǐng)大家點(diǎn)贊分享下。你的肯定是我最大的鼓勵(lì)和支持。

推薦閱讀

10萬+的短視頻被批量生產(chǎn)了,Python表示不服

視頻剪輯什么鬼?Python 帶你高效創(chuàng)作短視頻

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容