前言
作为抖音的重度使用患者,每天刷着视频笑哈哈😄,不亦乐乎。可是大家都知道,抖音下载的视频是带水印的。作为一个有强迫症的程序猿,这是绝对不允许的。网上许多的去水印工具,它们的原理是咋样的,是写了一种特别厉害的算法嘛。好奇心驱使我开始了研究。
短视频去水印
分析
我们从抖音的分享链接入手,从抖音复制的分享链接格式如下
2.82 wsr:/ Happy birthday to Kobe.%篮球 %曼巴精神 %科比生日 https://v.douyin.com/d8LpxMQ/ 复制佌鏈接,da鐦Dou音搜索,直接观看視频!
其中有个链接地址https://v.douyin.com/d8LpxMQ/
,我们放到浏览器里,发现这个链接重定向了,重定向的地址如下:
https://www.iesdouyin.com/share/video/6999605370222054663
好像也没啥用,我们抓下包看看有没有请求视频的接口,仔细找找找,叮。发现了 item_ids 的接口,后面跟的值就是重定向url的最后这部分(6999605370222054663),我判断这应该是视频的ID了。接口地址如下:
https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=6999605370222054663
接下来我们看看这个接口请求返回的数据,哇哦,当我点开Preview的时候,一下豁然开朗了,有视频的文案、作者、音乐、缩略图、地址等等
我拿出视频的地址后,复制到浏览器打开。视频url如下:
https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0d00fg10000c4hpfk3c77uar6l7cs90&ratio=720p&line=0
可是打开后发现,视频左上角的水印还是在啊。看着这个url中的 playwm,发现 wm和我项目名有点相似,不是watermark的缩写吗?我去掉 wm,然后复制到浏览器打开,神奇的一幕出现了,视频的水印没了,太激动了。视频无水印的地址如下:
https://aweme.snssdk.com/aweme/v1/play/?video_id=v0d00fg10000c4hpfk3c77uar6l7cs90&ratio=720p&line=0
原来抖音视频去水印这么简单啊,还想着视频算法什么的,只是简单分析就搞成了。哈哈,简单的让我有点感动🤭。
既然原理搞明白了,那写代码不是轻松加愉快嘛。
代码实现
我们复制的视频链接是一个混合文本的视频短链接,首先将链接提取出来,这个就用正则来处理吧
if len(re.findall('[a-z]+://[\S]+', content, re.I | re.M)) > 0:
return re.findall('[a-z]+://[\S]+', content, re.I | re.M)[0]
视频短链接提取出来后,需要对其进行请求重定向,来获取视频的 id。通过request 库来进行请求
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/92.0.4515.107 Safari/537.36'}
# url:重定向的url
response = requests.get(url, headers=header)
return response.url
我们需要对重定向得到的url进行截取视频id,来作为接口参数 item_ids的值
# realUrl:重定向得到的url
startUrl = realUrl[0:realUrl.index('?')]
id = startUrl[startUrl.rindex('/') + 1:len(startUrl)]
开始请求接口。GET请求,一个参数 item_ids
douyinUrl = 'https://www.iesdouyin.com/web/api/v2/aweme/iteminfo'
douyinParams = {
'item_ids': id
}
douyinResponse = requests.get(url=douyinUrl, params=douyinParams, headers=headers)
body = douyinResponse.text
json解析,拿到视频文案和视频地址。其中无水印视频链接的 playwm 要替换成 play
data = json.loads(body)
# 视频文案
videoTitle = data['item_list'][0]['desc']
# 视频带水印url
videoUrl = data['item_list'][0]['video']['play_addr']['url_list'][0]
# 视频无水印url
realVideoUrl = f'{videoUrl}'.replace('playwm', 'play')
最后,我们通过 webbrowser 库来打开浏览器,并播放视频,尽情享受无水印的快感吧
webbrowser.open(realVideoUrl)
所有代码如下:
import json
import re
import webbrowser
import requests
def get_url(content):
if len(re.findall('[a-z]+://[\S]+', content, re.I | re.M)) > 0:
return re.findall('[a-z]+://[\S]+', content, re.I | re.M)[0]
return None
def get_redirect_url(url, header):
# url:重定向的url
response = requests.get(url, headers=header)
return response.url
if __name__ == '__main__':
douyinUrl = 'https://www.iesdouyin.com/web/api/v2/aweme/iteminfo'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/92.0.4515.107 Safari/537.36'}
inputContent = input('请输入视频链接:')
if inputContent.strip() is not None:
if get_url(inputContent) is not None:
realUrl = get_redirect_url(get_url(inputContent), headers)
# realUrl:重定向得到的url
startUrl = realUrl[0:realUrl.index('?')]
id = startUrl[startUrl.rindex('/') + 1:len(startUrl)]
douyinParams = {
'item_ids': id
}
if realUrl.__contains__('www.douyin.com/video'):
douyinResponse = requests.get(url=douyinUrl, params=douyinParams, headers=headers)
body = douyinResponse.text
print(douyinResponse.url)
data = json.loads(body)
print(data['item_list'][0]['desc'])
# 视频文案
videoTitle = data['item_list'][0]['desc']
# 视频带水印url
videoUrl = data['item_list'][0]['video']['play_addr']['url_list'][0]
# 视频无水印url
realVideoUrl = f'{videoUrl}'.replace('playwm', 'play')
print(realVideoUrl)
webbrowser.open(realVideoUrl)
发表评论 取消回复