#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#author:Wos

import psutil
import requests
import os
import random
import string
import sys
import time
import pyperclip
import subprocess



proxies = {}
pxy = ""
fname = ""


logo = '''
  __  __ _____   _ 
 |  \/  |__ / | | |
 | |\/| ||_ \ |_| |
 |_|  |_|___/\___/ 

'''
temp_path = "/tmp/m3u8temp/"
hdr = {
    "upgrade-insecure-requests": "1",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"
}   

#check whether the pn program is running,if so,wait utill it exit
def check_is_end(pn):
    while True:
        j = 0
        for i in psutil.process_iter():
            if str(pn) in str(i):
                j += 1
        if j == 0:
            return True
        else:
            time.sleep(3)
            continue


def get_real_m3u8(url):
    premain = "/".join(str(url).split("/")[:-1])+"/"
    premain_ = "/".join(str(url).split("/")[:3])
    cnt = 0
    while True:
        try:
            if cnt < 3:
                res = requests.get(url,headers=hdr,timeout=(3,7))
                break
            else:
                return
        except:
            cnt += 1
            continue
    temp = str(res.text).split("\n")
    for i in temp:
        if not str(i).startswith("#") and str(i).strip().endswith(".m3u8"):
            if str(i).strip().startswith("http"):
                return get_real_m3u8(str(i).strip())
            else:
                t = str(i).strip().split("/")[1]
                if str(t) in str(premain):
                    url2 = premain_+str(i).strip()
                else:
                    url2 = premain+str(i).strip()
                return get_real_m3u8(url2)
    return url


def vname_str():
    ran_str = ''.join(random.sample(string.ascii_letters, 8))
    return ran_str

def proxy_select():
    global proxies,pxy
    os.system('clear')
    print(logo)
    print("copy m3u8 link,then continue")
    print("if download failed,try enable proxy")
    sid = input("enable proxy Y/N(N):")
    if sid == 'Y' or sid == 'y':
        proxies = {"http":"127.0.0.1:7890"}
        pxy = "--all-proxy=http://127.0.0.1:7890"
    else:
        proxies = {}
        pxy = ""



def normal_download(url):
    cmdline = 'aria2c \"'+url+'\" -c --allow-overwrite=true --check-certificate=false --file-allocation=none --max-tries=3 -s8 -x8 -k 1M '+pxy
    print(cmdline)
    os.system(cmdline)


def m3u8_download(url):
    try:    
        premain = '/'.join(str(url).split("/")[:3])+'/'
        #premain is main domain of link
        print(premain)
        while True:
            try:
                print("mission 0_1")
                r = requests.get(url,headers=hdr,proxies=proxies,timeout=(3,7))
                break
            except:
                continue

        with open(temp_path+"0.m3u8",'wb') as code:
            code.write(r.content)
            code.close()
        print("mission 0...")

        #premain_ is sub domain


        while True:
            if "xhcdn.com/" in str(url) or "xvideos-cdn.com/" in str(url) or ".com//m3u8/" in str(url) or "xnxx-cdn.com" in str(url):
                premain_ = '/'.join(str(url).split("/")[:-1])+'/'
                #xvideo sub domain
                print("premain_:"+premain_)
                break
            elif "urlset/" in str(url):
                premain_ = (str(url).split("urlset/")[0])+'urlset/'
                #pornhub sub domain
                print("premain_2:"+premain_)
                break
            elif (len(str(url).split('/'))) > 5 and '?' in str(url):
                premain_ = '/'.join(str(url).split("/")[:-1])+'/'
                break
            else:
                break
        while True:
            try:
                r = requests.get(url,headers=hdr,proxies=proxies,timeout=(3,7))
                break
            except:
                continue
        l = r.text.split('\n')

        dl = [] #file download link list
        cl = [] #downloaded file directory list
        el = [] #renamed file list

        #check whether need to change the main domain  of resource
        k = 0
        while k < len(l):
            if str(l[k]).startswith('http'):
                print("check whether exist sub domain...")
                pm = '/'.join(str(l[k]).split("/")[:3])+'/'
                #if sub domain is different with main domain,replace main domain with sub domain
                print("pm:"+pm)
                if pm != premain:
                    premain = pm
                break
            elif not str(l[k]).startswith('http') and not str(l[k]).startswith("#"):
                ln= len(str(l[k]).split('/'))
                print("check whether exist sub domain...")
                if ln > 2:
                    premain = '/'.join(str(url).split("/")[:3])+'/'
                else:
                    premain = '/'.join(str(url).split("/")[:-1])+'/'


                break
            k += 1

        print("resource main domain:"+premain)

        tl = []
        tl_ = []
        key = "" #key file link
        iv = ""
        kn = ""  #key file name
        #check whether stream is encrypt
        k = 0
        try:
            while k < len(l):
                if str(l[k]).startswith("#") and "AES-128,URI=" in str(l[k]):
                    tmp = str(l[k]).split("AES-128,URI=\"")[1].split('\"')[0]
                    kn = "crypt.key"
                    iv = str(l[k]).split(",IV=")[1]
                    if tmp.startswith('http'):
                        key = tmp
                    else:
                        premain_key = '/'.join(str(url).split("/")[:-1])+'/'

                        key = premain_key+tmp
                    break
                k += 1
        except:
            key = ""
            kn = ""
            iv = ""
            pass

        #download key file
        if key == "":
            print("none encryption resource")
        else:
            print("encryption file")
            print("key link:"+str(key))
            print("key name:"+str(kn))
            print("iv:"+str(iv))
            #download the key to local
            cmdline = "aria2c "+str(key)+" --allow-overwrite=true --file-allocation=none --out="+str(kn)+' -d '+temp_path
            print(cmdline)
            os.system(cmdline)


        #readline of 0.m3u8 file

        if os.path.exists(temp_path+'0.m3u8'):
            f = open(temp_path+'0.m3u8','r',encoding='utf-8')    
            while True:
                i = f.readline()
                if i:
                    if str(i).startswith('#') and "AES-128,URI=\"" in str(i):
                        temp = ""
                        temp = str(i).split("AES-128,URI=\"")[0]+"AES-128,URI=\""+kn+"\",IV="+str(iv)+"\n"
                        tl_.append(temp)
                    elif not str(i).startswith('#'):
                        temp = ""
                        if str(i).startswith('http'):
                            temp = str(i).strip('/').strip('\n')+"\n"
                        elif not str(i).startswith("http"):
                            temp = premain+str(i).strip('/').strip('\n')+"\n"
                        tl.append(temp)
                        fn = str(i).split("/")[-1]
                        if not str(fn).endswith('.ts') or not str(fn).endswith('flv'):
                            temp = str(fn).split('?')[0]
                        else:
                            temp = str(fn)
                        tl_.append(temp+"\n")
                    else:
                        tl_.append(str(i))
                else:
                    break



        #print(tl[0:3])
        #print(tl_[0:3])

        #clean 1.m3u8和2.m3u8 file
        if os.path.exists(temp_path+'1.m3u8'):
            f = open(temp_path+'1.m3u8','w',encoding='utf-8').close()
        if os.path.exists(temp_path+'2.m3u8'):
            f = open(temp_path+'2.m3u8','w',encoding='utf-8').close()


        if key != "":
            #m3u8 file for download  
            f = open(temp_path+'1.m3u8',"a",encoding='utf-8')
            for j in tl:
                f.write(j)
            f.close()

            #m3u8 file for combine
            f = open(temp_path+'2.m3u8','a',encoding='utf-8')
            for j in tl_:
                f.write(j)
            f.close()            



        mode = 0 #0:default filename mode 1:comstomize filename mode
        em = 0 #0:stream no hidden,1:stream hidden
        first=True

        j = 1        

        for i in l:
            if  not str(i).startswith('#') and str(i) != "":
                if first == True and str(i).startswith("http"):
                    res = requests.get(str(i)).content[:4]
                    if res == b'\x89PNG':
                        em = 1
                        print("this file is image stealth")


                if str(i).startswith("http") and str(i).endswith('m3u8'):
                    print("mission 1...")
                    url2 = str(i)
                    print(url2)
                    return m3u8_download(url2)
                elif 'ts' not in str(i) and not str(i).startswith("http") and str(i).endswith('m3u8'):
                    print("mission 2...")
                    ln = len(str(i).split("/"))
                    if ln > 3:
                        premain = '/'.join(str(premain).split("/")[:3])+'/'
                        url2 = premain+str(i).lstrip('/')
                    else:
                        url2 = premain+str(i).lstrip('/')
                    print(url2)
                    return m3u8_download(url2)

                elif str(i).startswith('http') and em == 1:
                    print("mission 3...")
                    dl.append(str(i).strip('/').strip('\n')+"\n")
                    if first == True:                   
                        cl.append("file \'"+temp_path+"0.ts\'\n")
                        el.append("0.png")
                    elif first == False:
                        cl.append('file \''+temp_path+str(j)+".ts\'\n")
                        el.append(str(j)+".png")
                        j += 1
                    mode = 1                        
                elif not str(i).startswith('http') and em == 1:
                    print("mission 4...")
                    dl.append(premain+str(i).strip('/').strip('\n')+"\n")
                    if first == True:                   
                        cl.append("file \'"+temp_path+"0.ts\'\n")
                        el.append('0.png')

                    elif first == False:
                        cl.append("file \'"+temp_path+str(j)+".ts\'\n")
                        el.append(str(j)+'.png')
                        j += 1                    
                    mode = 1                        


                elif 'urlset/' in str(url) or 'xhcdn.com' in str(url) or ".com//m3u8/" in str(url) or ".m3u8?cdn" in str(url) or "xnxx-cdn.com" in str(url):
                    #pornhub、xhamster、91porn
                    print("mission 5...")
                    print("premain_:"+premain_)
                    print("premain:"+premain)
                    if ".m3u8?cdn" in str(url) or 'xhcdn.com' in str(url) or "xnxx-cdn.com" in str(url) or "urlset/" in str(url):
                        print("xhamster resource parser...")
                        if not str(i).startswith('http'):
                            dl.append(premain_+str(i).strip('/').strip('\n')+"\n")
                            cl.append('file \''+temp_path+str(i).strip('/').split('?')[0].split('.ts')[0].split('/')[-1]+".ts\'\n")               
                        else:
                            dl.append(str(i).strip('/').strip('\n')+"\n")
                            cl.append('file \''+temp_path+str(i).strip('/').split('?')[0].split('.ts')[0].split('/')[-1]+".ts\'\n")
                    else:
                        print("x porn resource parser...")
                        if str(i).startswith('http'):
                            dl.append(str(i).strip('/').strip('\n')+"\n")
                            cl.append('file \''+temp_path+str(i).strip('/').split('?')[0].split('.ts')[0].split('/')[-1]+".ts\'\n")               
                        else:
                            dl.append(premain_+str(i).strip('/').strip('\n')+"\n")
                            cl.append('file \''+temp_path+str(i).strip('/').split('?')[0].split('.ts')[0].split('/')[-1]+".ts\'\n")                        


                elif 'xvideos-cdn.com/' in str(url):
                    #xvideo resource
                    print("mission 6...")
                    dl.append(premain_+str(i).strip('/').strip('\n')+"\n")
                    cl.append('file \''+temp_path+str(i).strip('/').split('.ts')[0]+".ts\'\n")

                elif str(i).startswith('http'):
                    #normal stream type
                    print("mission 7...")
                    dl.append(str(i).strip('/').strip('\n')+"\n")
                    cl.append('file \''+temp_path+str(i).strip('/').split('/')[-1].split('.ts')[0]+".ts\'\n")
                elif not str(i).startswith('http'):
                    print("mission 8...")
                    dl.append(premain+str(i).strip('/').strip('\n')+"\n")
                    cl.append('file \''+temp_path+str(i).strip('/').split('/')[-1]+"\'\n")

                first = False









        f = open(temp_path+fname+'2.txt',"a",encoding='utf-8')    
        for j in cl:
            f.write(j)
        f.close()

        f = open(temp_path+fname+'.txt',"a",encoding='utf-8')    
        for j in dl:
            f.write(j)
        f.close()

        if key == "":
            if mode == 0:
                print("mission 9...")
                cmdline = 'aria2c -i '+temp_path+fname+'.txt --max-tries=3 --allow-overwrite=true --file-allocation=none -c -s8 -x8 -k 1M '+pxy+' -d '+temp_path
                os.system(cmdline)
            elif mode == 1:
                print("mission 10...")
                k = 0
                for k_ in dl:
                    cmdline = 'aria2c \"'+str(k_).strip('\n')+'\" --max-tries=3 --allow-overwrite=true --file-allocation=none -c -s8 -x8 -k 1M --out='+temp_path+el[dl.index(k_)]+' '+pxy
                    subprocess.Popen(cmdline,shell=False)  
                    k += 1
                    if k < 16:
                        k += 1
                        continue
                    else:
                        k = 0
                        if check_is_end("aria2c"):
                            continue


            #combine ts file
            if check_is_end("aria2c"):
                if em == 1:
                    print("decrypting the image...")
                    for j_ in el:
                        try:
                            data = ""
                            dx = 0
                            with open(temp_path+str(j_),'rb') as f:
                                data_ = bytearray(f.read())
                                if dx == 0:
                                    dx = data_.find(b"G@\x00\x10\x00\x00")
                                data = (data_[dx:])
                                f.close()
                            with open(temp_path+str(j_).replace('.png','.ts'),'wb') as f:
                                f.write(data)
                                f.close()
                        except:
                            command = 'cp '+temp_path+str(el.index(j_)-1)+'.ts '+temp_path+str(el.index(j_))+'.ts'
                            print(command)
                            os.system(command)
                            continue


            print("none encryption file combine...")
            cmdline3 = 'ffmpeg -f concat -safe 0 -i '+temp_path+fname+'2.txt'+' -c copy '+fname+'.mp4 -y '
            os.system(cmdline3)







        else:
            #encryption file combine
            print("decrypting the video...")
            cmdline = 'aria2c -i '+temp_path+'1.m3u8 -c --allow-overwrite=true --check-certificate=false --file-allocation=none --max-tries=3 -s8 -x8 -k 1M '+pxy+' -d '+temp_path
            os.system(cmdline)
            print("encryption video combine...")
            cmdline2 = 'ffmpeg -allowed_extensions ALL -i '+temp_path+'2.m3u8 '+' -c copy -absf aac_adtstoasc '+fname+'.mp4'
            print(cmdline2)
            os.system(cmdline2)

    except:
        pass

def clean_tempfile():
    if check_is_end('ffmpeg'):
        os.system('rm /tmp/m3u8temp/*.* -rf')





if __name__ == '__main__':
    proxy_select()
    url = pyperclip.paste()
    if str(url).strip().startswith("http"):
        url = str(url).replace("\\/","/")
        print(url)
        if ".mp4" in str(url) and ".m3u" not in str(url):
            normal_download(url)
        else:
            fname = vname_str()
            if not os.path.isdir(temp_path):
                os.mkdir(temp_path)            
            url = get_real_m3u8(url)
            m3u8_download(url)
        clean_tempfile()