m3u8的视频下载以及.ts文件解密

声明:请你提前去下载Python和ffmpeg,不然本文对你有强烈不适。

忙了一晚上,终于把某网站的某m3u8视频下载下来了

在某网站上看到喜欢的视频自然要下载,解析了半天,把那网站的m3u8文件搞了下来,然后发现:

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1024000,RESOLUTION=1280x714
/ppvod/9******D

我的发,这特么是毛,搞毛线!然后我就各种查资料,了解到了ppvod是个管视频切片的玩意(好像),怒了,搞个下载视频那么麻烦让用户咋下载啊!
打了会游戏,想到这路径是个根目录,就机智的把m3u8原网站地址给他加在了前面,果不其然,真的m3u8文件到手。

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:11
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI=".../key.key"
#EXTINF:10.083,
.../*****.ts
#EXTINF:10.417,
.../*****.ts
#EXTINF:10.417,
.../*****.ts
#EXTINF:10.417,
.../*****.ts

你以为这样就结束了吗?
辣眼睛,一打开那文件,全是路径,关键是那些路径还全不是绝对路径,用Python数了一下,共有2257个切片文件。自闭。
又去打了会游戏,想到我不是有Python吗?急中生智,用Python把里面路径全改为绝对的了。

with open("D:/.../**.m3u8","r") as f:
  with open("D:/.../**2.m3u8","w") as w:
    while 1:
      n = f.readline()
      if n == '':#读到头了
        break
      if n[0] == '/' #判断是否是路径(别照搬,可能这里有点不一样)
        n = "https://xx.xxx.xxx/"+n
      w.write(n)

这下清晰多了。

试了下vlc,网上的转换教程,一个5小时的视频要一点一点放完,我忍不下去,拿出Python就搞了个多线程下载:

import sys, os, requests
from threading import Thread

class m3u8thread:
    def __init__(self,p,apath,threadnum):
        self.tn = threadnum
        self.path = p
        self.list = []
        self.num = 0
        self.sucnum = 0
        self.sp = apath

    def start(self):
        n = '' #计算下载链接
        with open(self.path,'r') as f:
            while 1:
                n = f.readline()
                if n == '':
                    break
                if n[0:4] == 'http':
                    self.list.append(n)
        self.num = len(self.list)
        print("Down .ts file num:",self.num)

        downsize = self.num // self.tn
        #开启线程
        self.tpool = []
        for i in range(self.tn):
            self.tpool.append(Thread(target=self.down,args=(i,downsize*i,downsize*(i+1))))
        for i in self.tpool:
            i.start()

    def down(self,u,start,end):
        if u+1 == self.tn:
            end = self.num
        print("Thread-%s started. Downsize: from %s to %s."%(u,start,end))
        downpart = self.list[start:end]

        p = 0
        for i in downpart:
            i = i.replace('\n','')
            filename = os.path.split(i)[1]
            file = requests.get(i)
            if file.status_code > 300 or file.status_code < 200:
                sys.stderr.write("File '"+filename+"' cannot download. code: "+str(file.status_code))
                continue
            with open(self.sp+"/"+filename,'wb') as f:
                f.write(file.content)
                self.sucnum += 1

源码自己写的,直接搬上来了,看看有甚么要改的。
在用上面那代码下载的时候,直接漏了20个.ts文件,花了我半天时间从2000文件里去找
调用:
a=m3u8thread(m3u8文件路径,保存ts文件的文件夹,线程数)
a.start()

不得不说爽,20分钟搞定,我赛扬J1800 @2.41Ghz双核轻松带动10线程。
文件是下载下来了,听说有某些网站还特地搞加密,我一瞧,我这特么就被加密了。
网上找了半天,终于看到m3u8开头的key文件:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:11
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI=".../key.key" (咱在这)

把那key文件下载下来,果断看网上用ffmpeg,又改了一次m3u8内的视频路径,全改为本地的,代码我就不贴了,这忒简单。

Win+R调出cmd,cd到m3u8文件夹路径下

这里我搞了半天,提醒一句:
m3u8内的ts文件路径必须要本地绝对路径!!!还必须用"\"这个斜杠!!!
比如D:/tmp/sssss.ts就会报错:
[hls…] ctypto:D:/tmp/D:/tmp/sss.ts 是个啥文件?
必须用D:\tmp\sss.ts

然后就开始了最后一步:

ffmpeg -allowed_extensions ALL -protocol_whitelist "file,http,cr
ypto,tcp" -i [m3u8文件] -c copy [输出文件]

成功!

一些错误:
运行后报错找不到key路径?
解决:把.key文件下载下来,m3u8开头的URI="…“修改为本地路径,可以不用”\"。比如

#EXT-X-KEY:METHOD=AES-128,URI="D:/aaa.key"

你可能感兴趣的:(Python,m3u8,python)