吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2021|回复: 24
收起左侧

[Python 原创] 【改良】用python+ffmpeg下载m3u8为mp4

  [复制链接]
icer233 发表于 2025-2-1 16:11
思路:下载m3u8中的每个ts文件,将m3u8里的ts的链接替换成本地ts地址,用ffmpeg下载这个新的m3u8
经测试,这样比直接用ffmpeg下载要快一点
把ffmpeg.exe放在py文件同一目录即可
源码:
[Python] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import logging
import asyncio
import subprocess
from pathlib import Path
 
import m3u8
import aiohttp
from tqdm.asyncio import tqdm_asyncio
 
 
async def load_m3u8(s, m3u8_url):
    async with s.get(m3u8_url) as r:
        return m3u8.loads(await r.text(), uri=m3u8_url)
 
 
async def fetch(s, index, segment):
    ts_name = f'{index}.ts'
    with open(f'ts/{ts_name}', 'wb') as f:
        async with s.get(segment.absolute_uri) as r:
            async for chunk in r.content.iter_chunked(64 * 1024):
                f.write(chunk)
 
 
async def download_ts(s, playlist):
    Path('ts').mkdir(exist_ok=True)
    tasks = (fetch(s, index, segment) for index, segment in enumerate(playlist.segments))
    await tqdm_asyncio.gather(*tasks)
 
 
def new_m3u8(playlist):
    for index, segment in enumerate(playlist.segments):
        segment.uri = f"ts/{index}.ts"
    playlist.dump('new.m3u8')
 
 
def m3u82mp4(capture_output=True):
    subprocess.run(['ffmpeg',
                    '-allowed_extensions', 'ALL',
                    '-i', 'new.m3u8',
                    '-c', 'copy',
                    'output.mp4'], check=True, capture_output=capture_output)
 
 
def clean_up():
    for ts_file in Path('ts').iterdir():
        ts_file.unlink()
    Path('ts').rmdir()
    Path('new.m3u8').unlink()
 
 
async def main():
    connector = aiohttp.TCPConnector(limit=limit)
    async with aiohttp.ClientSession(connector=connector) as s:
        logging.info(f'正在读取m3u8链接:{m3u8_url}')
        playlist = await load_m3u8(s, m3u8_url)
        logging.info('正在下载ts文件')
        await download_ts(s, playlist)
    logging.info('正在生成新的m3u8文件')
    new_m3u8(playlist)
    logging.info('正在转换新的m3u8文件为mp4文件')
    m3u82mp4()
    logging.info('正在清理临时文件')
    clean_up()
 
 
if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
    limit = 30
    m3u8_url = 'url'
    asyncio.run(main())

免费评分

参与人数 4吾爱币 +12 热心值 +4 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
天空宫阙 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
laozhang4201 + 1 + 1 热心回复!
seazer + 2 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

guhuishou 发表于 2025-2-1 17:06
这个想法不错,github上还有一个类似的项目N_m3u8DL-CLI,可以作为参考
pyjiujiu 发表于 2025-2-3 23:10
看了几遍,好像明白了,是先下载ts文件,然后用ffmpeg 从本地加载,转换成 mp4
异步没有自己实现 加入event loop ,猜测应该是 fetch(s, index, segment) 中的s.get(segment.absolute_uri) ,借助aiohttp.ClientSession() 自动加的。
之前手动写过 下载ts 文件的脚本,速度倒在其次,经常遇到 一次性下不全(多线程一直挂起),然后是解密的问题(不同的网站方案还不一样)
159357ssy 发表于 2025-2-1 16:30
leijun666 发表于 2025-2-1 17:17
需要下载哪些依赖包呢,有加密的是否也支持
一场荒唐半生梦 发表于 2025-2-1 18:26
楼主有打包的吗?
Echo001 发表于 2025-2-1 18:47
有点东西,下载好用
hope1314520 发表于 2025-2-1 18:53

这个想法不错,
 楼主| icer233 发表于 2025-2-1 19:02
本帖最后由 icer233 于 2025-2-1 19:04 编辑
leijun666 发表于 2025-2-1 17:17
需要下载哪些依赖包呢,有加密的是否也支持

刚把解密的部分删了(
依赖的话,开头import的都装一下就行了,大多是自带的
 楼主| icer233 发表于 2025-2-1 19:03

没有,有需要的话我可以打包一下
52pe 发表于 2025-2-1 19:31
试了下:为什么我感觉并不快,反而还导致电脑比较卡顿呢?难道错觉?

个人建议加上重试,解密功能建议保留,可以依实际情况选择是否解密。感觉现在好多都是有加密的
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-5-18 17:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表