1. 起因

最近有个朋友给我发了个小电影。

地址是https://xxxxxx.m3u8, 当我使用微信直接打开的时候是可以播放的,但是使用edge打开的时候却直接跳转到了下载连接里,无奈,只能下载下来一个m3u8的文件。

这边先简单解释一下什么是m3u8的视频格式。

根据维基百科的解释,

M3U8 是 Unicode 版本的 M3U,用 UTF-8 编码。"M3U" 和 "M3U8" 文件都是苹果公司使用的 HTTP Live Streaming(HLS) 协议格式的基础,这种协议格式可以在 iPhone 和 Macbook 等设备播放。

我们使用Visual Studio Code或者其他编辑器打开m3u8文件,我们可以比较清楚地看到,其实就是一个utf-8编码的播放列表。

我们使用播放器播放的时候,实际上是在加载这些地址的视频片段。当我们直接访问这些链接的时候也是可以访问的。但是这样看起来依旧不太舒服,我们已经习惯了看一整段MP4的视频,并且还想把它存到本地自己搭建的NAS里,这样就可以长期播放了不是嘛。

2. 经过

为了方便,我先是下载了一些下载站里的m3u8下载器,但是免费的东西总是会有一定的局限的。这些下载工具虽然UI做的精美,但是尝试了几个之后发现根本不能用。其中有一个倒是成功把每个片段的文件下载下来了。然后再进行合并的时候,根本没有合并成功,却把之前下载的文件全删光了。

要不,还是自己实现吧。

由于只是实现一个小功能,并没有什么性能上的要求,因此决定使用python快速解决。

突然,我在pypi上发现了一个神奇的库。

import m3u8_to_mp4m3u8_to_mp4.download('http://videoserver.com/playlist.m3u8',tmpdir='/tmp/m3u8_xx')

根据提示,只需要两句话就能够把视频文件下载下来,并且使用ffmpeg(该包需要在电脑上先配置ffmpeg, 即执行指令"ffmpeg -version"有结果)将其打包成一个Mp4文件。

于是我兴致冲冲地用了一下,但是结果令人心凉。果然,轮子还是得自己造才行。

3. 造轮子

造轮子也不是从种树开始的,有方便的工具尽管可以使用,这边使用的Pypi里面的m3u8这个库,可以很快解析m3u8文件内容,同时还使用了pycryptodom这个库中的AES解密(实际上在本次案例中并没有用到)。

# encoding=utf-8
import m3u8
import requests
import datetime
import os
from Crypto.Cipher import AES
from Crypto import Random
import glob
# Request header, not necessary, see website change
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
}def download(ts_urls, download_path, keys=[]):if not os.path.exists(download_path):os.mkdir(download_path)decrypt = Trueif len(keys == 0) or keys[0] is None:  # m3u8 will get [None] if not key or []decrypt = Falsefor i in range(len(ts_urls)):ts_url = ts_urls[i]file_name = ts_url.uriprint("start download %s" %file_name)start = datetime.datetime.now().replace(microsecond=0)try:response = requests.get(file_name, stream=True, verify=False)except Exception as e:print(e)returnts_path = download_path+"/{0}.ts".format(i)if decrypt:key = keys[i]iv = Random.new().read(AES.block_size)cryptor = AES.new(key.encode('utf-8'), AES.MODE_CBC)with open(ts_path,"wb+") as file:for chunk in response.iter_content(chunk_size=1024):if chunk:if decrypt:file.write(cryptor.decrypt(chunk))else:file.write(chunk)end = datetime.datetime.now().replace(microsecond=0)print("total time:%s"%(end-start))def merge_to_mp4(dest_file, source_path, delete=False):with open(dest_file, 'wb') as fw:files = glob.glob(source_path + '/*.ts')for file in files:with open(file, 'rb') as fr:fw.write(fr.read())print(f'\r{file} Merged! Total:{len(files)}', end="     ")if delete:os.remove(file)if __name__ == "__main__":url = "test.m3u8"video = m3u8.load(url)print(video.data)download(video.segments, 'tmp', video.keys)merge_to_mp4('result.mp4', 'tmp')

我们将步骤分为两部分,(1)为下载ts文件, (2)为合并ts文件为mp4

(1)下载ts文件

下载ts文件相对简单。根据m3u8库解析出来的地址,我们直接进行request请求获得相应的response。 这时候需要注意的是,如果m3u8解析出来的文件中含有key,说明该文件是通过该key值进行AES加密的,需要对response进行解密后再保存下来,如果没有可以直接保存。

在m3u8库解析m3u8文件中,如果文件不带有key,那么获取到的keys=[None], 它的长度是1,所以不能通过直接判断keys的长度是否为0来决定需不需要解密。

(2)合并成Mp4文件

合并的步骤比较简单,就是将ts按顺序读取之后写到同一个文件里。这边需要注意的是,在保存ts文件时要按照一定的顺序保存,合并时也使用该顺序,否则就会有一种乱序插入的感觉。

使用Python下载本地的m3u8文件相关推荐

  1. 使用python下载简单的m3u8视频

    使用python下载简单的m3u8视频 流程 #mermaid-svg-Ql5Fjr0zKXuzjuAS {font-family:"trebuchet ms",verdana,a ...

  2. python下载的库要放到哪里-Python下载url并保存文件的三种方法

    本节主要内容: 学习python下载Url并保存文件的方法. Python中通常是使用Http利用urllib或urllib2模块来下载url中的内容. 当然也可以利用ftplib从ftp站点下载文件 ...

  3. [转] 三种Python下载url并保存文件的代码

    原文 三种Python下载url并保存文件的代码 利用程序自己编写下载文件挺有意思的. Python中最流行的方法就是通过Http利用urllib或者urllib2模块. 当然你也可以利用ftplib ...

  4. python下载网页上的文件_用Python下载一个网页保存为本地的HTML文件实例

    Python打开网页并另存为静态html怎么实现 如何用python把网页上的文本内容保存下来那一世的长情,谱一首长相思,冷了多少凄凉,漫了多少青丝,化作多少烟雨,吹散多少世间情!徒悲,奈何,这一世, ...

  5. 电脑播放已下载本地的m3u8缓存视频文件

    经常在网上看视频,不管是电脑上还是手机上!最近几年除了m3u8格式的视频流,其它格式都很少见了.而为啥不用种子下载,是因为要浏览下剧情,看是否喜欢! 原先有简单的视频合并工具软件,但现在能用的很少了! ...

  6. Python爬虫:从m3u8文件里提取小视频的正确操作

    文章目录 前言 1. HLS协议与m3u8文件 2. 第三方库----m3u8 3. 合成mp4文件 4. 完整代码 5. 结束语 前言   在网上爬取的小视频(.ts格式)打不开怎么搞?使用IDM下 ...

  7. 使用Python下载蓝奏云文件

    蓝奏云下载 2022年04月21日编写 # -*- coding: utf-8 -*-## Python3 ## 下载蓝奏云文件 ## 参考链接:https://blog.csdn.net/qq_45 ...

  8. 下载了python在哪里写代码-通过python下载FTP上的文件夹的实现代码

    # -*- encoding: utf8 -*- import os import sys import ftplib class FTPSync(object): def __init__(self ...

  9. python下载url_三种Python下载url并保存文件的代码详解

    利用程序自己编写下载文件挺有意思的. Python中最流行的方法就是通过Http利用urllib或者urllib2模块. 当然你也可以利用ftplib从ftp站点下载文件.此外Python还提供了另外 ...

  10. python下载url图片或文件

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.Get方法 二.urllib方法 三.可能遇到的问题 1.urllib.error.HTTPError: HTTP ...

最新文章

  1. Elasticsearch Aggregation 多个字段分组统计 Java API实现
  2. 决策树(Decision Tree)和随机森林
  3. python加载包出错_python导入Pmw包运行提示一下错误
  4. 数据可视化组队学习:《Task02 - 艺术画笔见乾坤》笔记
  5. html生成1-32位随机数,如何生成一个32位的随机数 | 求索阁
  6. JavaScript与HTML交互——事件
  7. php fast cgi nginx,通过fast-cgi连接php-fpm和nginx之间的连接是持...
  8. 使用系统调用pipe建立一条管道线_使用Unixbench对服务器综合性能打分及测试结果...
  9. 0x01第一个汇编程序
  10. 异步与多线程的区别 线程安全 (总结)
  11. mybatis使用oracle自动生成主键
  12. LINUX下载编译libc(glibc)
  13. 哈佛大学凌晨4点半的景象
  14. Oracle查询优化改写技巧与案例总结一
  15. bex5执行oracle语句,BeX5
  16. Arcgis中的空间数据拓扑理论及规则
  17. phpcms修改了配置文件之后出现Warning: date() expects parameter 2 to be long..错误
  18. c语言1076素数,九度OJ 1076:N的阶乘 题解
  19. VBA生成KML文件
  20. 【设计模式系列学习笔记】5、依赖倒转原则和里氏代换原则

热门文章

  1. 雷云3启动无响应解决办法
  2. 如何查看MacBook Pro硬盘序列号
  3. FreeSWITCH之默认端口
  4. 最新一键修改手机MAC地址和路由器wifi物理地址
  5. 人工智能智能制作PPT构想---论文与PPT介绍
  6. 制作PPT如何快速绘制透视立体图
  7. 39份AICon全球人工智能与机器学习技术大会 · 北京站2021(PPT汇总)
  8. java如何美化按钮_css美化button按钮
  9. 重磅!Pandownload开发者被抓,一代神器落幕!
  10. iOS:iOS开发非常全的三方库、插件等等