hj170520 发表于 2020-6-6 09:47

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

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

就是不是按照原有的顺序来的,求解决{:301_991:}

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

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.肯定作了自己的修改。还望见谅。{:301_1008:}

hj170520 发表于 2020-6-6 09:49

{:301_971:}如果我描述的有问题,可以直接用代码运行一遍,产生一个shipin.mp4,看了就知道问题了。{:301_974:}

idiotsir 发表于 2020-6-6 10:01

多线程下载,任务谁先下载完,先写进去,顺序就会乱掉,建议先全部下载完,再按顺序读取,写入mp4文件

Ldfd 发表于 2020-6-6 10:02

是不是能用ffmpeg合并呢

冰楓丶殘瀷 发表于 2020-6-6 10:02

应该按文件名排,m3u8文件名都排好的

hj170520 发表于 2020-6-6 10:05

idiotsir 发表于 2020-6-6 10:01
多线程下载,任务谁先下载完,先写进去,顺序就会乱掉,建议先全部下载完,再按顺序读取,写入mp4文件

对呀,多线程下载就会出现这个问题。谢谢大佬
下载完了再提取二进制数据写入吗?{:301_974:}

hj170520 发表于 2020-6-6 10:06

冰楓丶殘瀷 发表于 2020-6-6 10:02
应该按文件名排,m3u8文件名都排好的

按上面那个大佬的回复,应该是我用了多线程。
本来是应该按顺序写进去的,但最终是谁先下载好了谁先写入。{:301_998:}
那这个情况下会怎么解决呢?

冰楓丶殘瀷 发表于 2020-6-6 10:07

hj170520 发表于 2020-6-6 10:06
按上面那个大佬的回复,应该是我用了多线程。
本来是应该按顺序写进去的,但最终是谁先下载好了谁先写入 ...

你先下载完再合并处理

hj170520 发表于 2020-6-6 10:08

Ldfd 发表于 2020-6-6 10:02
是不是能用ffmpeg合并呢

我电脑没装成功,所以另辟蹊径,用直接写入的方式。
后来发现是因为用了多线程。{:301_996:}
这种情况下如果想用多线程,就必须用ffmpeg咩?

hj170520 发表于 2020-6-6 10:09

冰楓丶殘瀷 发表于 2020-6-6 10:07
你先下载完再合并处理

那就必须用到ffmeg这个软件吗?
还是怎么办呢?{:301_997:}
页: [1] 2
查看完整版本: python 下载m3u8格式视频,直接用'ab'方式写进一个mp4文件播放顺序出问题