躺着就能涨粉?Python自动化短视频搬运(五)|视频处理

脚本三:视频处理及信息获取

前几章我们完成了基于Pytube的所有Youtube操作,包括频道轮询和影片下载,这个功能保证了我们Python自动化脚本已经能够守候在油管后台,对关注的频道进行第一时间的高清影片获取。按照我们第一篇中描述的流程,接下来,在发布到我们自己的自媒体平台之前,需要对视频本身做一些必要的处理,并提取一些视频的信息如封面帧,标题翻译等。前者是为了避免平台搬运监测(本篇只是浅测有效,具体还需要更多的扩展),后者是为发布到中文自媒体平台做资料准备。

1. 视频处理

视频处理的工具是在本系列第二篇文章里所介绍过的FFmpeg:《躺着就能涨粉?Python自动化短视频搬运(二)|合并影片》,在那篇文章里我们用FFmpeg完成了最基本的音频文件和视频文件的合并。本篇我们将继续深入使用FFmpeg执行更多的操作。

FFmpeg有大量的滤镜(filter)功能,只要输入合适的参数,就能得到经过滤镜处理的视频。在我的实际应用中,我主要用了锐化,对比度,亮度,缩放及裁剪等常用的滤镜,下面就一一来介绍:

使用滤镜的格式:

在介绍具体滤镜前,让我们先把FFmpeg针对多滤镜的命令框架搭一下,分享下我使用的命令:

ffmpeg -i <源文件> -filter_complex <滤镜列表> -c:v libx264 \
 -c:a copy -f mp4 <输出文件> -y

<源文件>:需要进行处理的原始视频文件
<滤镜列表>:下面会介绍
<输出文件>:经过滤镜处理完的视频文件

在此系列的第二篇《躺着就能涨粉?Python自动化短视频搬运(二)|合并影片》的实战例子中,我们有个油管下载和合成的现成视频文件:v1080p+audio.mp4,我们可以直接用它来做测试,并命令输出文件:v1080p+audio_output.mp4。

ffmpeg -i v1080p+audio.mp4 -filter_complex <滤镜列表> -c:v libx264 \
-c:a copy -f mp4 v1080p+audio_output.mp4 -y

<滤镜列表>的格式是 "filter1=para1, filter2=para2, filter3=para3, ..." (注意,双引号是必须的)

ffmpeg -i v1080p+audio.mp4 -filter_complex "filter1=para1, filter2=para2, \
filter3=para3, ..." -c:v libx264 -c:a copy -f mp4 v1080p+audio_output.mp4 -y

滤镜1: 锐化

因为毕竟是搬运来的视频,画面的给人的距离感还是挺远的,为了增加“亲切感”,一般我会使用锐化效果来让画面更锐利,细节可以更加容易的体现出来。

锐化的滤镜名称是unsharp(竟然是unsharp?),它的一般格式是unsharp=x:y:c,x和y是明亮度矩阵xy,默认是5*5,而c是“浓度”,默认值是1,快速应用的话,只修改c就能达到想要的目的。c的数字越大,画面越锐利,但随之而来的就是噪点的增加,所以要选择适中的参数,基于我的实战经验,对于国外下载的视频,使用5:5:2的效果比较好。

unsharp=5:5:2

我们在命令行下面尝试下组合好的锐化命令:

$ ffmpeg -i v1080p+audio.mp4 -filter_complex "unsharp=5:5:2" -c:v libx264 \
-c:a copy -f mp4 v1080p_audio_output.mp4 -y

耐心等待一段时间的FFmpeg处理log结束后,就可以在当前文件夹下找到v1080p+audio_output.mp4文件,播放该文件和源文件对比,能看到画面有比较明显的锐化效果,对清晰度有比较大的提升。


左图为锐化后,右图为原图

滤镜2: 对比度和亮度

这个比较简单,参数格式是"eq=contrast=c:brightness=b..."其中,c是对比度值,1是不调整,>1是对比度加强,<1是对比度减弱,我目前使用的值是1.2。b是亮度值,0是不调整,>0是变亮,<0是变暗,我目前使用的值是0.1。另外,eq滤镜下还有不少其他的参数,如色温等,有需求完全可以自行添加。
我们在命令行下面尝试下组合好的对比度和亮度调整命令:

$ ffmpeg -i v1080p+audio.mp4 -filter_complex "eq=contrast=1.2:brightness=0.1" \
-c:v libx264 -c:a copy -f mp4 v1080p_audio_output.mp4 -y

耐心等待后,播放两个视频,查看区别:


左图为调整完对比度和亮度,右图为原图

滤镜3:缩放和裁剪

缩放和裁剪在视频剪辑里非常常用,同样用FFmpeg也是非常地方便。首先看缩放滤镜,它的滤镜格式是scale=x:y,其中x是缩放后的x方向像素数目,y是缩放后的y方向像素数目,比如原视频的分辨率是1024*640,如果scale=1025:641就是指放大图像,scale=1023:639就是指缩小图像。如果想保持原视频的长宽比,可以把x或y的值设成-1,如scale=1280:-1。
在实际应用中,光把视频画面放大,提交到平台后往往还是会呈现出一样的大小,如果我们想要画面更大,通常需要在放大画面的同时配合裁剪,把画面裁切到原来一样的大小。裁剪的滤镜格式是crop=w:h:x:y,其中w是裁剪后的x像素数目,h是y像素数目,x是从原视频的左边开始第几个像素开始截取,y是在从原视频的上方开始第几个像素开始截取。如我们想要一个1024640的视频,并画面的左上角是从原视频的1020位置开始裁剪:crop=1024:640:10:20。
现在我们尝试把测试视频略微放大,并裁减到原尺寸(原视频分辨率为1080*1920):

$ ffmpeg -i v1080p+audio.mp4 -filter_complex "scale=1180:-1, crop=1080:1920:150:100" \
-c:v libx264 -c:a copy -f mp4 v1080p_audio_output.mp4 -y

效果如下:


左图为放大裁剪后的视频,右图为原视频

合并滤镜

最后,我们把三组滤镜合并在一起,以一句FFmpeg执行以上所有操作:

$ ffmpeg -i v1080p+audio.mp4 -filter_complex "unsharp=5:5:2, \
                                              eq=contrast=1.2:brightness=0.1, \
                                              scale=1180:-1, crop=1080:1920:150:100" \
          -c:v libx264 -c:a copy -f mp4 v1080p_audio_output.mp4 -y

最后的执行效果:


左图为滤镜后的视频,右图为原视频

好了,这就是我们需要的待发布视频了。我们只要把这句FFmpeg命令加入到python代码里即可:

import os
os.system(f"ffmpeg -i {input_file} -filter_complex \"unsharp=5:5:2, \
                                              eq=contrast=1.2:brightness=0.1, \
                                              scale=1180:-1, crop=1080:1920:150:100\" \
          -c:v libx264 -c:a copy -f mp4 {output_file} -y")

2. 获取和编辑封面

由于发布到自媒体平台时,平台都会要求提供一张封面图用于展示使用,如果不主动提供,系统往往会默认使用第一帧或自动随机选一帧,这样一般展示效果不佳。建议我们自己可以主动从视频里获取一帧图片,作为封面图,在Youtube里,可以使用pytube调用接口得到原视频作者提供的封面,但是经过我的测试,这些图片分辨率都很低,没有办法下载到原图。所以我们还是使用强大的FFmpeg,从视频里“抽帧”。抽帧的细节就不介绍了,总的来说使用I帧比较保险,在自动化脚本里,就定义获取影片的第一个I帧作为封面图。抽I帧的命令如下:

ffmpeg -i {source_file} -vf "select=eq(pict_type\\,I)" \
           -vframes 1  -vsync vfr -qscale:v 2 -f image2 {output_file} -y

我们就用本章新创建的视频文件v1080p_audio_output.mp4做测试:

ffmpeg -i v1080p_audio_output.mp4 -vf "select=eq(pict_type\,I)" \
           -vframes 1  -vsync vfr -qscale:v 2 -f image2 v1080p_audio_output.jpeg -y

可以看到,我们得到了一张还不错的封面图。


v1080p_audio_output.jpeg

同样,合并到python代码里:

os.system(f"ffmpeg -i {input_file} -vf \"select=eq(pict_type\\,I)\" \
           -vframes 1  -vsync vfr -qscale:v 2 -f image2 {output_file} -y")

光有封面图片还不够专业,一般的视频封面我们都会见到一些醒目的艺术字,来简要描述视频内容,达到吸睛的效果,当然这个python也是完全可以做到的。

封面图加字幕

编辑图片的功能,我们会同时使用opencv和pillow。这两个都是非常强大的图像处理第三方库,如果只是给画面添加文字,opencv足矣,不过我们需要对文字有些艺术化编辑,如边框高亮等,那就需要pillow比较强大的绘图功能。

首先,先下载安装这两个库,并加上计算库numpy:

$ pip install opencv-python
$ pip install pillow
$ pip install numpy

在代码里导入它们,主要导入模块名和库名并不相同:

import cv2
import numpy as np
from PIL import ImageFont, ImageDraw, Image

我们可以用cv2把图片读取进来给PIL使用,我们接下来的操作都是基于draw对象来进行,在测试中我们就使用之前生成的现成文件v1080p_audio_output.jpeg:

img = cv2.imread("./v1080p_audio_output.jpeg")
imgpil = Image.fromarray(img)
draw = ImageDraw.Draw(imgpil)

draw.text()函数是pillow中用来给图片加字幕的方法,因为我们需要给字幕加彩色边框,所以需要一定的巧妙处理。我没有找到直接可以使用的边框接口,自己写了一个text_board函数,主要功能就是黄色的文字周边2个像素写一圈白色的相同文字,最后在效果上起到了边框的效果。(这里的实现不用太纠结,无脑抄代码即可)

def text_border(draw, text, x, y, font, shadowcolor, fillcolor):
    draw.text((x-2, y), text, font=font, fill=shadowcolor)
    draw.text((x+2, y), text, font=font, fill=shadowcolor)
    draw.text((x, y-2), text, font=font, fill=shadowcolor)
    draw.text((x, y+2), text, font=font, fill=shadowcolor)
    draw.text((x-2, y-2), text, font=font, fill=shadowcolor)
    draw.text((x+2, y-2), text, font=font, fill=shadowcolor)
    draw.text((x-2, y+2), text, font=font, fill=shadowcolor)
    draw.text((x+2, y+2), text, font=font, fill=shadowcolor)
    draw.text((x, y), text, font=font, fill=fillcolor)

接下来,我们需要设置一下字体,你可以从系统字体库或直接到网上下载免费的.ttf字体文件,存放到代码所在文件夹下。我使用的是汉仪笔染甜甜圈 W字体免费下载和在线预览-字体天下下载下来的HYBiRanTianTianQuanW-2.ttf,比较适合做封面字幕。有了字体文件,并设置字体大小80,我们就用pillow导入,生成font对象:

fontpath = "./HYBiRanTianTianQuanW-2.ttf"
fontsize = 80
font = ImageFont.truetype(fontpath, fontsize)

接着让我们来随意定义一段需要绘制的文字:

title = "一段不错的街头舞蹈!"

我们就可以调用text_border()绘制文字图像了,这段文字的起始位置在100*400,(0,0,0)为黄色字体,(0,255,255)为白色边框:

text_border(draw, title, 100, 400, font, (0,0,0), (0,255,255))

最后,把绘制完draw对象的impil,用numpy和cv2规整保存进v1080p_audio_output_with_title.jpeg文件里。

retext = np.array(imgpil)
cv2.imwrite("./v1080p_audio_output_with_title.jpeg", retext)

让我们来最终效果,挺醒目的!


v1080p_audio_output_with_title.jpeg

3. 文字翻译

上文中描述了如何得到封面图和为该封面图添加标题,那这个文字本身从哪里来呢?当然你可以自定义或为每个视频都固定同一个标题,作为自动化脚本,更好的方式当然是获取到原版影片的标题。这里就涉及到第一篇中的内容《躺着就能涨粉?Python自动化短视频搬运(一)|下载影片》,通过Pytube获得youtube影片的title,这里快速把代码再复习一遍:

from pytube import YouTube
video = YouTube("https://www.youtube.com/watch?v=tO_L8bik10k")
title = video.title

由于是从国外网站下载的影片,它们都是英文标题,而在国内的视频平台上,英文标题很难吸引绝大多数人的关注,因此我们需要自动翻译成中文。这里推荐这里推荐translators库,它能自动对接到指定翻译接口上进行自动的全文翻译。同样下载安装translators:

$ pip install translators

在代码中对title字符串进行外中翻译,这里我选择iciba接口,感觉对外译中把握得比较好,当然其他也都可以用。

import translators as ts
title_cn = ts.iciba(title, to_language='zh-CN')
print(title)
print(title_cn)

打印:

Los Angeles Clippers vs. Brooklyn Nets Full Game Highlights | Nov 12 | 2022-23 NBA Season
洛杉矶快船队vs。布鲁克林篮网队全比赛亮点|11月12日| 2022-23 NBA赛季

通过这一篇的介绍,我们成功生成了一张带有中文字幕的封面图,和这一段经过翻译的中文标题,供我们后面发布使用。接下来我们就可以向自己的视频账号进行搬运了。

进入下一篇:《躺着就能涨粉?Python自动化短视频搬运(六)|自动发布》

返回上一篇:《躺着就能涨粉?Python自动化短视频搬运(四)|多频道管理》

本篇用到的代码:

thumbnails.py

import cv2
import numpy as np
from PIL import ImageFont, ImageDraw, Image

def text_border(draw, text, x, y, font, shadowcolor, fillcolor):
    draw.text((x-2, y), text, font=font, fill=shadowcolor)
    draw.text((x+2, y), text, font=font, fill=shadowcolor)
    draw.text((x, y-2), text, font=font, fill=shadowcolor)
    draw.text((x, y+2), text, font=font, fill=shadowcolor)
    draw.text((x-2, y-2), text, font=font, fill=shadowcolor)
    draw.text((x+2, y-2), text, font=font, fill=shadowcolor)
    draw.text((x-2, y+2), text, font=font, fill=shadowcolor)
    draw.text((x+2, y+2), text, font=font, fill=shadowcolor)
    draw.text((x, y), text, font=font, fill=fillcolor)

img = cv2.imread("v1080p_audio_output.jpeg")
imgpil = Image.fromarray(img)
draw = ImageDraw.Draw(imgpil)

fontpath = "./HYBiRanTianTianQuanW-2.ttf"
fontsize = 80
font = ImageFont.truetype(fontpath, fontsize)
title = "一段不错的街头舞蹈!"
text_border(draw, title, 100, 400, font, (0,0,0), (0,255,255))
retext = np.array(imgpil)
cv2.imwrite("./v1080p_audio_output_with_title.jpeg", retext) 

trans.py

import translators as ts
from pytube import YouTube

video = YouTube("https://www.youtube.com/watch?v=tO_L8bik10k")
title = video.title
print(title)
title_cn = ts.iciba(title, to_language='zh')
print(title_cn)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,718评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,683评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,207评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,755评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,862评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,050评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,136评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,882评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,330评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,651评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,789评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,477评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,135评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,864评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,099评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,598评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,697评论 2 351

推荐阅读更多精彩内容