如何以编程方式下载 Python 中 blob 中引用的 m3u8 视频?

问题描述 投票:0回答:2

请注意,这个问题与我们如何下载 blob url 视频[已关闭]不同,因为它需要无需与浏览器进行人工交互

我有以下问题:

  • 我有一个 URL 列表。它们指向具有相同底层结构的 HTML 页面。
  • 页面中间有一个图片;单击时,它会加载播放器。
  • 播放器作为 blob 引用 m3u8 播放列表,尽管这在 HTML 本身中不可见(它在 Chrome 的“网络”选项卡中可见)。
  • 播放器播放短视频。

我需要做什么:

  • 以编程方式访问各种 URL。获取 HTML 并单击图像播放器。
  • 获取 blob 引用并使用该引用来获取 m3u8 播放列表。
  • 以视频形式下载流(以 gif 形式下载可加分)。

请注意,该解决方案不需要与浏览器进行人工交互。 API 方面,输入应该是 URL 列表,输出应该是视频/gif 列表。

如果您想测试您的解决方案,可以在

此处找到示例页面。

我的理解是我可以使用Selene获取HTML并点击图像来启动播放器。但是,我不知道如何处理 blob 以获得 m3u8,然后将其用于实际视频。

python web-scraping beautifulsoup m3u8 m3u
2个回答
2
投票
只要稍微挖掘一下,您就不需要单击任何按钮。当您单击按钮时,它会调用 master.m3u8 文件。使用开发工具,您可以拼凑出请求的 URL。问题是,第一个文件不包含实际视频的链接。您拼凑另一个请求以获得最终的 m3u8 文件。从那里,您可以使用其他 SO 链接下载视频。它是分段的,因此不能直接下载。您可以取消注释下面的 print 语句,查看每个 m3u8 文件包含的内容。这也会循环浏览页面

import re for i in range(6119, 6121): url = 'https://www2.nhk.or.jp/signlanguage/sp/enquete.cgi?dno={}'.format(str(i)) page = requests.get(url) soup = BeautifulSoup(page.text, 'html.parser') print(soup.find(onclick=re.compile('signlanguage/movie'))) # locate the div that has the data we need video_id = soup.find(onclick=re.compile('signlanguage/movie')).get('onclick').split(',')[1].replace("'","") m3u8_url = 'https://nhks-vh.akamaihd.net/i/signlanguage/movie/v4/{}/{}.mp4/master.m3u8'.format(video_id[-1], video_id) # this m3u8 file doesn't contain download links, the next one does; so download and save that one r = requests.get(m3u8_url) # print(r.text) m3u8_url_2 = r.text.split('\n')[2] # get first link; high bandwidth r2 = requests.get(m3u8_url_2) # print(r2.text) # there are other ways to download the file, i'm just creating a new one with the data read and writing to a file fn = video_id + '.m3u8' with open(fn, 'w+') as f: f.write(r2.text) f.close()
    

0
投票
通常需要下载多个 m3u8 文件,重新编码为 mp4(例如)并连接到一个文件中。在 bash 中更容易。该解决方案适用于 Linux,但很容易针对其他操作系统进行修改。 使用以下想法:

我们如何下载 blob url 视频 如何使用 FFmpeg 连接两个 MP4 文件? 如何使用 ffmpeg 从视频中提取音频?

下载片段时可能有数十个或数百个,并且 URL 可能包含验证数据。例如下载该视频:

https://areena.yle.fi/1-66667313 对于第一段,人们会得到这样的东西:

https://ylekaodamd.akamaized.net/s/fhls/p/1955031/sp/195503100/serveFlavor/entryId/1_jljzhdfz/v/1/ev/9/flavorId/1_z7f4kk80/name/a.mp4/index。 m3u8/seg-1-v1-a1.ts?__hdnea__=st=1702651289~exp=1702737689~acl=/s/fhls/p/1955031/sp/195503100/serveFlavor/entryId/1_jljzhdfz/v/1/ev/9 /flavorId/1_z7f4kk80/name/a.mp4/index.m3u8/*~hmac=f43398b42ee3c627ab04546afc7795991cd3b33426e5173c2fe9d35496c90fa1

请注意“seg-1”,表示第 1 段,该视频最多有 116 个段。另请注意 hmac,它会通过刷新页面而改变。 要获取 116 个段:

for i in $(seq 1 116); do ffmpeg -i "https://ylekaodamd.akamaized.net/s/fhls/p/1955031/sp/195503100/serveFlavor/entryId/1_jljzhdfz/v/1/ev/9/flavorId/1_z3go9mvo/name/a.mp4/index.m3u8/seg-$i-v1-a1.ts?__hdnea__=st=1702651290~exp=1702737690~acl=/s/fhls/p/1955031/sp/195503100/serveFlavor/entryId/1_jljzhdfz/v/1/ev/9/flavorId/1_z3go9mvo/name/a.mp4/index.m3u8/*~hmac=182271152d7547f189a5d5d3c041a7bc7b4fc223915a00be0e838fddc140c206" -c copy -bsf:a aac_adtstoasc "$i.mp4" done
现在我们有 116 个 mp4 文件并将它们连接起来:

for i in $(seq 1 116); do echo "file $i.mp4" >> mylist.txt done ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4
将音频提取为 mp3:

ffmpeg -i output.mp4 -q:a 0 -map a output.mp3
    
© www.soinside.com 2019 - 2024. All rights reserved.