營銷號視頻生成器(Python)


網上最近很火的段子是各種營銷號的文案,比方說下面的段子

核桃核不能吞下去是怎么回事呢?核桃核相信大家都很熟悉,但是核桃核不能吞下去是怎么回事呢,下面就讓小編帶大家一起了解吧。核桃核不能吞下去,其實就是核桃核太大了,吞下去容易噎着,大家可能會很驚訝核桃核怎么會不能吞下去呢?但事實就是這樣,小編也感到非常驚訝。這就是關於核桃核不能吞下去的事情了,大家有什么想法呢,歡迎在評論區告訴小編一起討論哦!

其實我平時見到這些文案或者視頻都很少,因為我沒用過今日頭條、抖音之類的APP

然后我就在想,如果指定文案、BGM、視頻,給定這三個東西,能否批量生成營銷號視頻,於是就有了這個項目

項目說明我錄了個視頻放在B站了,源碼放在了Github

 

下面詳細說明一下代碼吧

設計思路
首先我把這個程序分為了以下幾步:

剪裁視頻→getVideo()
將台詞寫入文本→getText(file)
獲取視頻總時長→getLength(video)
給視頻添加背景音樂→add_audio(video, mp3, output='out.mp4')
給視頻添加字幕→subTitle(text_file, video_file, output='out_sub.mp4')
文本轉人聲→訊飛API
給視頻添加人聲→add_people(mp3_file, video_file)
清除中間生成的文件→clean()
1. 裁剪視頻
對於大部分營銷號視頻來說,長度都在45秒左右,我也沒有弄的太復雜,就直接將給定的mp4文件的前50秒保留了下來,其余的部分不要

def getVideo():
cmd = 'ffmpeg -y -i in.mp4 -ss 00:00:00 -t 00:00:50 -acodec copy -vcodec copy -async 1 in_sub.mp4'
subprocess.call(cmd, shell=True)


上面代碼的意思是在cmd命令行中執行cmd這句命令,這個命令的意思是將in.mp4從0秒開始,裁剪到50秒,並保存為in_sub.mp4文件

2. 將文本寫入台詞
這個其實是最簡單的,網上有很多“營銷號文案生成器”,我隨便找了個源碼借鑒了下。首先你需要在一個文本文件中設定好主體、事件、另一種說法,例如

 

那么他就會生成文案

核桃核不能吞下去是怎么回事呢?核桃核相信大家都很熟悉,但是核桃核不能吞下去是怎么回事呢,下面就讓小編帶大家一起了解吧。核桃核不能吞下去,其實就是核桃核太大了,吞下去容易噎着,大家可能會很驚訝核桃核怎么會不能吞下去呢?但事實就是這樣,小編也感到非常驚訝。這就是關於核桃核不能吞下去的事情了,大家有什么想法呢,歡迎在評論區告訴小編一起討論哦!

其實非常簡單,就是一個字符串替換

def getText(file): # 組裝台詞
    with open(file) as f:
        body = f.readline().strip()
        thing = f.readline().strip()
        other_word = f.readline().strip()
    
    # 主題框架
    txt = '''{}{}是怎么回事呢?:4:0
{}相信大家都很熟悉,但是{}{}是怎么回事呢?:7:4
下面就讓小編帶大家一起了解吧:3:11
{}{},其實就是{}:8:15
大家可能會很驚訝{}怎么會{}呢?:6:23
但事實就是這樣,小編也感到非常驚訝:5:29
這就是關於{}{}的事情了,大家有什么想法呢?:6:34
歡迎在評論區告訴小編一起討論哦!:5:40'''.format(body, thing, body, body, thing, body, thing, other_word, body, thing, body, thing)

    # 台詞寫入
    with open('text.txt', mode='w') as f:
        f.write(txt)

文本后面的數字代表意思分別是字幕的持續時間、開始出現的時間。比方說下面就讓小編帶大家一起了解吧這句話就會從第11秒開始出現,持續顯示3秒

3. 獲取視頻總時長
做這一步主要是考慮到BGM和視頻應該差不多時長,假如BGM有60秒,視頻只有50秒,那就會出現這樣一個現象,整個視頻的時長是60秒,但是當視頻播放到第50秒之后,畫面就不變化了,而BGM還在播放

所以這里獲取的視頻時長,是為了后面剪裁BGM使用的

但是又有人可能會覺得,你一開始不是設定了50秒,那這里為啥還要動態獲取時長,而不寫50秒呢?因為我考慮到后面的可擴展性,如果有用戶想要修改視頻時長,比方說改為60秒,那代碼就有很多地方也要修改。但是如果我用一個變量來代替,用戶就只需要修改第一步里的視頻時長即可
————————————————

def getLength(video): # 獲取視頻時長
    cmd = 'ffprobe -v quiet -select_streams v -show_entries stream=duration -of csv="p=0" {video}'.format(video=video)
    seconds = os.popen(cmd, 'r')
    seconds = math.ceil(float(seconds.read()))
    m, s = divmod(seconds, 60)
    h, m = divmod(m, 60)
    return "%02d:%02d:%02d" % (h, m, s)

由於ffmpeg這個庫對時間的格式有要求,必須是00:00:00這種格式,所以我稍微做了一些處理

4. 給視頻添加背景音樂
這一步里面又分三小步

裁剪BGM
降低BGM音量
給視頻添加BGM
為什么要降低BGM音量,是因為我在后續測試的過程中發現BGM聲音有點太大了,掩蓋住了人聲
————————————————

def add_audio(video, mp3, output='out.mp4'): # 將背景音樂添加到視頻中
    BGM = 'ffmpeg -i {mp3} -ss 00:00:00.0 -t {time} -acodec copy BGM.mp3'.format(mp3=mp3, time=total_time)
    subprocess.call(BGM, shell=True)

    volume = 'ffmpeg -i BGM.mp3 -vcodec copy -af "volume=-20dB" BGM_volume.mp3'
    subprocess.call(volume, shell=True)
    
    command = "ffmpeg -i {mp3} -i {video} -y {output}".format(video=video, mp3='BGM_volume.mp3', output=output)
    subprocess.call(command, shell=True)

給視頻添加字幕

添加字幕我用的是moviepy這個庫,它里面有一個TextClip方法,參數有很多,可以非常方便的添加字幕對象,然后將這些對象和視頻對象一起進行整合,就可以了

def subTitle(text_file, video_file, output='out_sub.mp4'):
    video1 = VideoFileClip(video_file)
    sentences = [] # 台詞列表
    with open(text_file) as f:
        text_tmp = f.readlines()
        for i in text_tmp:
            sentences.append(i.strip().split(':'))
    print(sentences)
    
    txts = [] # 所有字幕剪輯
    with open('args.txt') as f:
        color = f.readlines()[4].strip()
        for sentence, span, start in sentences:
            txt = (TextClip(sentence, fontsize=50, align='center', color=color, font='SimHei')
                    .set_position(("center","bottom")).set_duration(int(span)).set_start(int(start)))
            txts.append(txt)

    video2 = CompositeVideoClip([video1, *txts])
    video2.write_videofile(output)
6. 文本轉人聲
所有的步驟都可以自己完成,唯獨文本轉人聲不行,只能調用第三方接口,百度、騰訊、訊飛都可以,這里我用的訊飛的接口

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2LYUgs3u-1587353056943)(https://s1.ax1x.com/2020/04/20/JQAm8J.png#shadow)]

代碼也是使用的訊飛提供的demo(python3),由於太多了,就不在這放出來了

實現的時候有一個細節要提一下,就是如何做到字幕和人聲同步

從上面的添加字幕可以看出,字幕的各種時間都是設定死的,那么能操作的也就是有人聲了。具體操作我是這樣做的,每一個字幕,生成一個人聲,一共有8段字幕,所以我有8個mp3文件,由於人聲是無法設置持續時間的,只能設置什么時間開始發聲,即只能設置開始時間,所以我把每一個mp3文件的開始時間都設置成每個字幕的開始時間相同。這樣做就會出現一個現象,假設某一段文本非常短,很快就讀完了,字幕也消失了,但是下一段字幕以及對應的人聲不會立即出現,而是單純的只有BGM,只有等這段字幕和人聲到點了,它們才會出現。不過我測試了實際效果並不突兀

7. 給視頻添加人聲

 
def addPeople(mp3_file, video_file):
    my_clip = VideoFileClip(video_file)
    audio_background = AudioFileClip(mp3_file)
    final_audio = CompositeAudioClip([my_clip.audio, audio_background])
    final_clip = my_clip.set_audio(final_audio)
    final_clip.write_videofile('final.mp4')

 

 

8. 清除中間生成的文件

這步也非常簡單,因為使用ffmpeg庫的時候,中間有一些臨時保存的mp3、mp4文件,在最后的時候刪除掉就行了

 

def addPeople(mp3_file, video_file):
    my_clip = VideoFileClip(video_file)
    audio_background = AudioFileClip(mp3_file)
    final_audio = CompositeAudioClip([my_clip.audio, audio_background])
    final_clip = my_clip.set_audio(final_audio)
    final_clip.write_videofile('final.mp4')

 


————————————————
版權聲明:本文為CSDN博主「數學家是我理想」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_37236745/article/details/105619051


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM