吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1862|回复: 19
收起左侧

[求助] python 下载m3u8格式视频,直接用'ab'方式写进一个mp4文件播放顺序出问题

[复制链接]
hj170520 发表于 2020-6-6 09:47
python 下载m3u8格式视频,直接用'ab'方式写进一个mp4文件播放顺序出问题!

就是不是按照原有的顺序来的,求解决

我的意思是不用软件合并怎么才能完成呢?

[Python] 纯文本查看 复制代码
import requests
import re
import threading
import queue
from decimal import Decimal
import os


url = 'https://iqiyi.cdn9-okzy.com/20200416/8987_cd3e4bfa/index.m3u8'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
data = {}
count = 0
q = queue.Queue()
ts_link_2 = []

'''先是下载一个"头部文件"'''
req = requests.get(url, headers=headers).text
# print(req)
ts_link_1 = re.findall(r'\n(.*?).ts',req)  # 寻找 Transport Stream文件格式
# print(ts_link_1)

'''再下载一个整个ts列表信息"'''
if len(ts_link_1) == 0:  # 判断是否不存在
    arr = req.split('\n')
    # print(arr)
    for i in arr:
        if "m3u8" in i:
            url = url.replace('index.m3u8',i)
            # print(url)
            req = requests.get(url, headers=headers).text
            ts_link_2 = re.findall(r'\n(.*?\.ts)', req)
            for ts in ts_link_2:
                q.put(ts)

# print(q.qsize())  # q.qsize 在接下来的作用就是一个动态的列表
# print(len(ts_link_2))

'''然后开始下载"'''


def download_ts(q):
    if not os.path.exists("./qs"):
        os.mkdir("./qs")
    while 1:  # 表示永远循环,除非循环内部有跳出语句
        bai = Decimal(str(1 - q.qsize() / len(ts_link_2))).quantize(Decimal('0.00'))
        # 用 1 - qsize(变量)来做百分比
        # Decimal('0.00') 保留三位有效数字
        print("\r 进度:" + str(bai * 100) + "%|100%", end="")
        name = q.get()  # 取出队列
        # print(name)
        newUrl = url.replace("index.m3u8", name)
        # print('\r' + newUrl)
        r = requests.get(newUrl, None, stream=True)
        # print(r.status_code) # 返回状态码
        if r.status_code == 200:
            open('./qs/shipin.mp4', 'ab').write(r.content)  # 二进制b写入
            # print("\n"+newUrl + "————下载成功!")
        else:
            print("\n" + newUrl + "————下载失败!")
        q.task_done()
        if q.empty():
            break

# 使用进程运算 速度明显改善


try:
    for i in range(20):  # 20个线程
        th = threading.Thread(target=download_ts, args=(q,))  # 注意 args=(q,)
        th.start()

except:
    print("Error: 无法启动线程")


上述的代码我也是“剽窃”坛友的,emmmm.肯定作了自己的修改。还望见谅。

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

 楼主| hj170520 发表于 2020-6-6 09:49
如果我描述的有问题,可以直接用代码运行一遍,产生一个shipin.mp4,看了就知道问题了。
idiotsir 发表于 2020-6-6 10:01
多线程下载,任务谁先下载完,先写进去,顺序就会乱掉,建议先全部下载完,再按顺序读取,写入mp4文件
Ldfd 发表于 2020-6-6 10:02
冰楓丶殘瀷 发表于 2020-6-6 10:02
应该按文件名排,m3u8文件名都排好的
 楼主| hj170520 发表于 2020-6-6 10:05
idiotsir 发表于 2020-6-6 10:01
多线程下载,任务谁先下载完,先写进去,顺序就会乱掉,建议先全部下载完,再按顺序读取,写入mp4文件

对呀,多线程下载就会出现这个问题。谢谢大佬
下载完了再提取二进制数据写入吗?
 楼主| hj170520 发表于 2020-6-6 10:06
冰楓丶殘瀷 发表于 2020-6-6 10:02
应该按文件名排,m3u8文件名都排好的

按上面那个大佬的回复,应该是我用了多线程。
本来是应该按顺序写进去的,但最终是谁先下载好了谁先写入。
那这个情况下会怎么解决呢?
冰楓丶殘瀷 发表于 2020-6-6 10:07
hj170520 发表于 2020-6-6 10:06
按上面那个大佬的回复,应该是我用了多线程。
本来是应该按顺序写进去的,但最终是谁先下载好了谁先写入 ...

你先下载完再合并处理
 楼主| hj170520 发表于 2020-6-6 10:08
Ldfd 发表于 2020-6-6 10:02
是不是能用ffmpeg合并呢

我电脑没装成功,所以另辟蹊径,用直接写入的方式。
后来发现是因为用了多线程。
这种情况下如果想用多线程,就必须用ffmpeg咩?
 楼主| hj170520 发表于 2020-6-6 10:09
冰楓丶殘瀷 发表于 2020-6-6 10:07
你先下载完再合并处理

那就必须用到ffmeg这个软件吗?
还是怎么办呢?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-26 15:45

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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