欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

10萬(wàn)+的短視頻被批量生產(chǎn)了,Python表示不服 - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設(shè)-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設(shè)/小程序開發(fā)/軟件開發(fā)

知識(shí)

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X(jué)表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營(yíng)銷的便利,運(yùn)營(yíng)的高效,讓網(wǎng)站成為營(yíng)銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!

您當(dāng)前位置>首頁(yè) » 新聞資訊 » 技術(shù)分享 >

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

發(fā)表時(shí)間:2019-9-14

發(fā)布人:葵宇科技

瀏覽次數(shù):39

640?wx_fmt=jpeg

黑客技術(shù) 點(diǎn)擊右側(cè)關(guān)注,了解黑客的世界! 640?wx_fmt=jpeg

640?wx_fmt=jpeg

Java開發(fā)進(jìn)階 點(diǎn)擊右側(cè)關(guān)注,掌握進(jìn)階之路! 640?wx_fmt=jpeg

640?wx_fmt=jpeg

Python開發(fā) 點(diǎn)擊右側(cè)關(guān)注,探討技術(shù)話題! 640?wx_fmt=jpeg
作者丨星安果
來(lái)源丨AirPython
640?wx_fmt=jpeg

1

目 標(biāo) 場(chǎng) 景


做過(guò)自媒體的朋友應(yīng)該都知道,「GIF動(dòng)畫視頻」有段時(shí)間在各大自媒體平臺(tái)很受歡迎。
前期有些自媒體大 V 靠搬運(yùn)一些搞笑、好玩的 GIF,然后利用剪輯軟件合成一段視頻,再添加一個(gè)節(jié)奏感強(qiáng)的 BGM 后,上傳各大自媒體平臺(tái)后,能帶來(lái)不錯(cuò)的閱讀量和收益。
640?wx_fmt=png
本篇文章的目的是帶大家利用 Python 實(shí)現(xiàn)制作 GIF 動(dòng)畫視頻,批量制作短視頻這一騷操作。


2

準(zhǔn) 備 工 作


首先,對(duì)視頻和背景音樂(lè)的剪輯,這里用到了「moviepy」庫(kù),通過(guò) pip3 安裝到虛擬環(huán)境中。

  
   # moviepy 用于視頻剪輯和背景音樂(lè)的合成、剪輯
pip3 install moviepy

另外,項(xiàng)目中需要利用「PIL」庫(kù)來(lái)分析、獲取 GIF 動(dòng)畫中的所有幀圖片。

  
   # 將GIF圖片轉(zhuǎn)為幀,需要對(duì)GIF進(jìn)行分析
pip3 install ffmpeg


編寫腳本之前,我們需要提前準(zhǔn)備一些 GIF 動(dòng)畫素材。當(dāng)然,你也可以去爬取一些搞笑、好玩的 GIF 動(dòng)畫。
另外再準(zhǔn)備一段 BGM 作為視頻的背景音樂(lè)。


3

編 寫 腳 本


第一步,我們需要把每一個(gè) GIF 動(dòng)畫轉(zhuǎn)為一段視頻。

由于 GIF 動(dòng)畫已經(jīng)是一段包含很多幀的視頻了,沒(méi)法直接通過(guò) moviepy 庫(kù)轉(zhuǎn)為一段普通視頻。
所以,這里需要對(duì) GIF 動(dòng)畫進(jìn)行分析,將動(dòng)畫轉(zhuǎn)為「靜態(tài)幀圖片」。

  
   def get_gif_frames(gif_path, temp_path):
"""
獲取一段GIf圖片下的所有靜態(tài)幀
get_gif_frames('./../gifs/3.gif', './../gif_temp/')
:return:
"""


# 分析gif圖片
mode = analyseImage(gif_path)['mode']

im = Image.open(gif_path)

i = 1
p = im.getpalette()
last_frame = im.convert('RGBA')

try:
while True:
# print("saving %s (%s) frame %d, %s %s" % (gif_path, mode, i, im.size, im.tile))

'''
If the GIF uses local colour tables, each frame will have its own palette.
If not, we need to apply the global palette to the new frame.
'''

if not im.getpalette():
im.putpalette(p)

new_frame = Image.new('RGBA', im.size)

'''
Is this file a "partial"-mode GIF where frames update a region of a different size to the entire image?
If so, we need to construct the new frame by pasting it>if
mode == 'partial':
new_frame.paste(last_frame)

new_frame.paste(im, (0, 0), im.convert('RGBA'))
new_frame.save(temp_path + '/%s-%d.png' % (''.join(os.path.basename(gif_path).split('.')[:-1]), i), 'PNG')

i += 1
last_frame = new_frame
im.seek(im.tell() + 1)
except EOFError:
# print('產(chǎn)生EOFError!!!')
pass

另外,我們下載的 GIF 動(dòng)畫的靜態(tài)幀圖片分辨率大概率是不一致的,所以對(duì)圖片批量修改分辨率「修改分辨率」變的很有必要。
這里將所有圖片的分辨率統(tǒng)一修改為 720*1080,在轉(zhuǎn)換的過(guò)程中,如果存在空白部分,就使用黑色進(jìn)行填充。

  
   def resize_image(target_image_path, target_size):
"""
調(diào)整圖片大小,缺失的部分用黑色填充
:param target_image_path: 圖片路徑
:param target_size: 分辨率大小
:return:
"""

image = Image.open(target_image_path)

iw, ih = image.size # 原始圖像的尺寸
w, h = target_size # 目標(biāo)圖像的尺寸
scale = min(w / iw, h / ih) # 轉(zhuǎn)換的最小比例

# 保證長(zhǎng)或?qū)?#xff0c;至少一個(gè)符合目標(biāo)圖像的尺寸
nw = int(iw * scale)
nh = int(ih * scale)

image = image.resize((nw, nh), Image.BICUBIC) # 縮小圖像
# image.show()

new_image = Image.new('RGB', target_size, (0, 0, 0, 0)) # 生成黑色圖像
# // 為整數(shù)除法,計(jì)算圖像的位置
new_image.paste(image, ((w - nw) // 2, (h - nh) // 2)) # 將圖像填充為中間圖像,兩側(cè)為灰色的樣式
# new_image.show()

# 覆蓋原圖片
new_image.save(target_image_path)


然后,將統(tǒng)一分辨率后的靜態(tài)幀圖片轉(zhuǎn)換為一段普通視頻。
在轉(zhuǎn)換為視頻之前,我們需要提供一個(gè)「合理的轉(zhuǎn)換幀率」來(lái)保證視頻播放的流暢性。由于最后需要將多段視頻合成為一段視頻,這里默認(rèn)指定幀率為 10幀/s。
GIF 動(dòng)畫原始的幀率、播放時(shí)長(zhǎng)等動(dòng)畫文件屬性值可以利用「imgpy」獲取到。

  
   def get_gif_info(gif_path):
"""
獲取gif文件的詳細(xì)信息
每一個(gè)gif的幀率不一樣,有的<10fps;有的>10fps
:param gif_path:
:return:
"""

with Img(fp=gif_path) as im:
# 1.有多少幀
frame_count = im.frame_count

# 2.圖片信息
# {'version': b'GIF89a', 'background': 31, 'duration': 70, 'extension': (b'NETSCAPE2.0', 795), 'loop': 0}
duration_pre = im.info.get('duration')

# 根據(jù)規(guī)律,除以7位實(shí)際的播放時(shí)長(zhǎng)
duration = duration_pre / 7

# 6.color palette
# print(im.mode_desc)

# print((frame_count, duration))

# 返回幀率和時(shí)長(zhǎng)
return (frame_count / duration), duration


最后,我們利用 moviepy 庫(kù)中的「ImageSequenceClip」類將這些圖片寫入到一個(gè)視頻文件中。

  
   def pics_to_video(pics_path, output_path, fps, duration):
"""
圖片轉(zhuǎn)為視頻
pics_to_video('./../gif_temp/', './../video_temp/temp1.mp4', 20)
:param pics_path:
:param output_path:
:return:
"""

image_paths = list(map(lambda x: pics_path + x, os.listdir(pics_path)))

# 注意:這里必須進(jìn)行一次排序,保證所有幀的順序是一致
image_paths = sort_strings_with_emb_numbers(image_paths)

# 過(guò)濾掉非圖片
image_paths = list(filter(lambda image_path: image_path.endswith('.png'), image_paths))

# 圖片剪輯類
clip = ImageSequenceClip(image_paths,
fps=fps)

# 寫成視頻之前,需要把gif都轉(zhuǎn)成同一個(gè)分辨率
clip.write_videofile(output_path)


循環(huán)上面的操作,就可以將所有的 GIF 動(dòng)畫轉(zhuǎn)換為一個(gè)普通視頻文件。
第二步是將所有的視頻文件進(jìn)行剪輯,寫入一個(gè)單獨(dú)的文件中。利用 moviepy 庫(kù)下面的 「 VideoFileClip 」可以非常快捷方便地完成這一操作。

  
   def compound_a_video(self, videos_path):
"""
合成一個(gè)視頻
:param videos_output:視頻集合的完整目錄
:return:
"""

# 定義一個(gè)數(shù)組
L = []

for video_path in videos_path:
# 載入視頻
video = VideoFileClip(video_path)
# 添加到數(shù)組
L.append(video)

# 拼接視頻
final_clip = concatenate_videoclips(L)

# 生成目標(biāo)視頻文件
final_clip.to_videofile(self.video_output_temp, fps=self.fps, remove_temp=False)

最后一步是往視頻中添加背景音樂(lè)。


首先是通過(guò) AudioFileClip 和 VideoFlieClip 獲取到視頻文件和音頻文件的播放時(shí)長(zhǎng),對(duì)播放時(shí)長(zhǎng)較長(zhǎng)的文件進(jìn)行截取處理。

  
   # 1.音頻文件
audioclip = AudioFileClip(self.bgm_path)

# 2.視頻文件
videoclip = VideoFileClip(self.video_output_temp)

# 3.獲取視頻和音頻的時(shí)長(zhǎng)
video_time = videoclip.duration
audio_time = audioclip.duration

print('視頻時(shí)長(zhǎng):%f,音頻時(shí)長(zhǎng):%f' % (video_time, audio_time))

# 4.對(duì)視頻或者音頻進(jìn)行裁剪
if video_time > audio_time:
# 視頻時(shí)長(zhǎng)>音頻時(shí)長(zhǎng),對(duì)視頻進(jìn)行截取
ideoclip_new = videoclip.subclip(0, audio_time)
audioclip_new = audioclip
else:
# 音頻時(shí)長(zhǎng)>視頻時(shí)長(zhǎng),對(duì)音頻進(jìn)行截取
videoclip_new = videoclip
audioclip_new = audioclip.subclip(0, video_time)

然后把音頻文件通過(guò) set_audio() 添加到視頻操作類中,最后重新寫入到一個(gè)新的視頻文件當(dāng)中。


  
   # 5.視頻中加入音頻
video_with_new_audio = videoclip_new.set_audio(audioclip_new)

# 6.寫入到新的視頻文件中
video_with_new_audio.write_videofile("mp4_with_audio.mp4",
codec='libx264',
audio_codec='aac',
temp_audiofile='temp-audio.m4a',
remove_temp=True
)


4

結(jié) 果 結(jié) 論


以上的腳本會(huì)對(duì)指定文件夾的的 GIF 動(dòng)畫文件分別生成一段普通視頻,然后把所有的視頻合成一段視頻,然后再添加一段 BGM 背景音樂(lè),最后寫入到一個(gè)新的視頻文件中,如此,就完成了制作一個(gè) GIF 視頻的操作。

當(dāng)然,本文只是提供一個(gè)思路,讓 Python 爬取一些有趣好玩的 GIF 動(dòng)畫進(jìn)而批量做成視頻,上傳各大自媒體平臺(tái),應(yīng)該也能獲取到不錯(cuò)的閱讀量。


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


源碼鏈接:

https://github.com/xingag/tools_python/tree/master/video_auto/%E5%88%B6%E4%BD%9CGIF%E8%A7%86%E9%A2%91


推薦↓↓↓

640?wx_fmt=jpeg

長(zhǎng)

關(guān)

?16個(gè)技術(shù)公眾號(hào)】都在這里!

涵蓋:程序員大咖、源碼共讀、程序員共讀、數(shù)據(jù)結(jié)構(gòu)與算法、黑客技術(shù)和網(wǎng)絡(luò)安全、大數(shù)據(jù)科技、編程前端、Java、Python、Web編程開發(fā)、Android、iOS開發(fā)、Linux、數(shù)據(jù)庫(kù)研發(fā)、幽默程序員等。

640?wx_fmt=png 萬(wàn)水千山總是情,點(diǎn)個(gè) “ 在看” 行不行

相關(guān)案例查看更多