VideoHelp Forum


Try StreamFab Downloader and download from Netflix, Amazon, Youtube! Or Try DVDFab and copy Blu-rays! or rip iTunes movies!


Try StreamFab Downloader and download streaming video from Youtube, Netflix, Amazon! Download free trial.


+ Reply to Thread
Page 3 of 5
FirstFirst 1 2 3 4 5 LastLast
Results 61 to 90 of 124
Thread
  1. Originally Posted by Dannyboi View Post
    Code:
    C:\Users\Maverick>pip uninstall pywidevine
    WARNING: Skipping pywidevine as it is not installed.
    
    C:\Users\Maverick>pip install 'pywidevine==1.4.3'
    ERROR: Invalid requirement: "'pywidevine==1.4.3'"

    ...

    Replace the single quotes with double as you're using CMD.

    Code:
    pip install "pywidevine==1.4.3"
    Quote Quote  
  2. psaframe
    Join Date
    Mar 2021
    Location
    Algeria
    Search PM
    Originally Posted by Dannyboi View Post
    Originally Posted by Diazole View Post
    Originally Posted by Dannyboi View Post

    Python310 doesnt have a space and i deleted the pywidevine folder and tried the cmd pip install pywidevine but getting this error now

    Code:
    Microsoft Windows [Version 10.0.19044.2364]
    (c) Microsoft Corporation. All rights reserved.
    
    C:\Users\Maverick>pip install pywidevine
    Requirement already satisfied: pywidevine in c:\users\Maverick\appdata\local\programs\python\python310\lib\site-packages (1.5.2)
    Requirement already satisfied: Unidecode<2.0.0,>=1.3.4 in c:\users\Maverick\appdata\roaming\python\python310\site-packages (from pywidevine) (1.3.6)
    Requirement already satisfied: lxml>=4.9.1 in c:\users\Maverick\appdata\local\programs\python\python310\lib\site-packages (from pywidevine) (4.9.1)
    Requirement already satisfied: pycryptodome<4.0.0,>=3.15.0 in c:\users\Maverick\appdata\local\programs\python\python310\lib\site-packages (from pywidevine) (3.15.0)
    Requirement already satisfied: requests<3.0.0,>=2.28.1 in c:\users\Maverick\appdata\roaming\python\python310\site-packages (from pywidevine) (2.28.1)
    Requirement already satisfied: pymp4<2.0.0,>=1.2.0 in c:\users\Maverick\appdata\local\programs\python\python310\lib\site-packages (from pywidevine) (1.2.0)
    Requirement already satisfied: protobuf==4.21.6 in c:\users\Maverick\appdata\roaming\python\python310\site-packages (from pywidevine) (4.21.6)
    Requirement already satisfied: click<9.0.0,>=8.1.3 in c:\users\Maverick\appdata\local\programs\python\python310\lib\site-packages (from pywidevine) (8.1.3)
    Requirement already satisfied: colorama in c:\users\Maverick\appdata\local\programs\python\python310\lib\site-packages (from click<9.0.0,>=8.1.3->pywidevine) (0.4.6)
    Requirement already satisfied: construct==2.8.8 in c:\users\Maverick\appdata\local\programs\python\python310\lib\site-packages (from pymp4<2.0.0,>=1.2.0->pywidevine) (2.8.8)
    Requirement already satisfied: idna<4,>=2.5 in c:\users\Maverick\appdata\local\programs\python\python310\lib\site-packages (from requests<3.0.0,>=2.28.1->pywidevine) (2.10)
    Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\users\Maverick\appdata\local\programs\python\python310\lib\site-packages (from requests<3.0.0,>=2.28.1->pywidevine) (1.26.5)
    Requirement already satisfied: charset-normalizer<3,>=2 in c:\users\Maverick\appdata\local\programs\python\python310\lib\site-packages (from requests<3.0.0,>=2.28.1->pywidevine) (2.1.1)
    Requirement already satisfied: certifi>=2017.4.17 in c:\users\Maverick\appdata\local\programs\python\python310\lib\site-packages (from requests<3.0.0,>=2.28.1->pywidevine) (2022.9.24
    That's not an error.

    Run:

    Code:
    pip uninstall pywidevine
    pip install 'pywidevine==1.4.3'
    so i downloaded it from github and added it manually and getting:

    C:\Users\Maverick\Desktop\c4-dl-High bitrate>python .\c4-dl.py --download --wvd "C:\Users\Maverick\Desktop\c4-dl-High bitrate\widevine_device.wvd" --url "https://cf.jos.c4assets.com/CH4_08_02_900_73860001001001_001/CH4_08_02_900_73860001001001_001_J01.ism/stream.mpd?c3.ri=13504108658373752707&mpd_segment_ template=time&filter=8typeDD2video26688DisplayHeig htED2889668systemBitrateC4800000999CCtype1D2video2 &ts=1672773728&e=600&st=SkDQwuKTllNeol04d_ATccif2i rw2icc9KCOtk-gPHo"
    [!] Failed getting asset ID !!!
    Traceback (most recent call last):
    File "C:\Users\Maverick\Desktop\c4-dl-High bitrate\c4-dl.py", line 528, in <module>
    main()
    File "C:\Users\Maverick\Desktop\c4-dl-High bitrate\c4-dl.py", line 460, in main
    asset_id = get_asset_id(url)
    File "C:\Users\Maverick\Desktop\c4-dl-High bitrate\c4-dl.py", line 179, in get_asset_id
    init_data = json.loads(init_data.group(1))
    AttributeError: 'NoneType' object has no attribute 'group'

    C:\Users\Maverick\Desktop\c4-dl-High bitrate>pause
    Press any key to continue . . .


    and this when i tried your way:

    C:\Users\Maverick>pip uninstall pywidevine
    WARNING: Skipping pywidevine as it is not installed.

    C:\Users\Maverick>pip install 'pywidevine==1.4.3'
    ERROR: Invalid requirement: "'pywidevine==1.4.3'"
    my god. i hate noobs as ******* hell
    Quote Quote  
  3. i done everything but getting this now

    Code:
    C:\Users\Maverick\Desktop\all4_new>python .\c4-dl.py --download --wvd "C:\Users\Maverick\Desktop\c4-dl-High bitrate\widevine_device.wvd" --url "https://www.channel4.com/programmes/warplane-workshop/on-demand/73860-001"
    Traceback (most recent call last):
      File "C:\Users\Maverick\Desktop\all4_new\c4-dl.py", line 528, in <module>
        main()
      File "C:\Users\Maverick\Desktop\all4_new\c4-dl.py", line 478, in main
        device = Device.load(wvd)
      File "C:\Users\Maverick\AppData\Local\Programs\Python\Python310\lib\site-packages\pywidevine\device.py", line 164, in load
        with Path(path).open(mode="rb") as f:
      File "C:\Users\Maverick\AppData\Local\Programs\Python\Python310\lib\pathlib.py", line 1117, in open
        return self._accessor.open(self, mode, buffering, encoding, errors,
    FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\Maverick\\Desktop\\c4-dl-High bitrate\\widevine_device.wvd'
    
    C:\Users\Maverick\Desktop\all4_new>pause
    Press any key to continue . . .
    Quote Quote  
  4. Originally Posted by Dannyboi View Post
    i done everything but getting this now
    FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\Maverick\\Desktop\\c4-dl-High bitrate\\widevine_device.wvd'
    Oh dear.

    I got you this far, if you can't work that one out yourself then you shouldn't be using this script.


    Originally Posted by naim2007 View Post
    my god. i hate noobs as ******* hell
    Haha
    Quote Quote  
  5. @Dannyboi

    Advice for the future: use virtual environments for stuff like this. They let you install and mess around without disturbing the rest of the system. So when you get into a mess like this one, you can just start over in seconds.
    Quote Quote  
  6. Originally Posted by Diazole View Post
    Originally Posted by Dannyboi View Post
    i done everything but getting this now
    FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\Maverick\\Desktop\\c4-dl-High bitrate\\widevine_device.wvd'
    Oh dear.

    I got you this far, if you can't work that one out yourself then you shouldn't be using this script.


    Originally Posted by naim2007 View Post
    my god. i hate noobs as ******* hell
    Haha
    im missing widevine_device.wvd how do i get/ generate it i forgot?

    fixed it on my own thanks

    C:\Users\Maverick\Desktop\all4_new>python .\c4-dl.py --download --wvd "C:\Users\Maverick\Desktop\all4_new\amlogic_mbox_v 4.1.0-android_99908892_4445_l3.wvd" --url "https://www.channel4.com/programmes/warplane-workshop/on-demand/73860-001"
    ************************************************** ************************************************** ********************
    [ URL ] https://www.channel4.com/programmes/warplane-workshop/on-demand/73860-001
    [CONTENT]
    [CONTENT]
    [CONTENT]
    [ MPD ] http://ak.dash01.stream.c4assets.com/wvmod-stream/CH4_33_05_42_73860001001001_001_HD.m...38938848403648
    ************************************************** ************************************************** ********************
    [#9df255 53MiB/1.6GiB(3%) CN:16 DL:7.2MiB ETA:3m44s]

    script is so much better than the old one and it obtains keys and decrypts the files thanks for updating and fixing it
    Last edited by Dannyboi; 3rd Jan 2023 at 15:03.
    Quote Quote  
  7. So Anyone got a way to download and decrypt 1080p MY5 Content??
    Quote Quote  
  8. Member
    Join Date
    Dec 2021
    Location
    Scotland
    Search Comp PM
    Originally Posted by Dannyboi View Post
    So Anyone got a way to download and decrypt 1080p MY5 Content??
    You cannot get what ain't there in the first place
    Quote Quote  
  9. Originally Posted by deccavox View Post
    Originally Posted by Dannyboi View Post
    So Anyone got a way to download and decrypt 1080p MY5 Content??
    You cannot get what ain't there in the first place
    it is there the My5 app streams in 1080p on samsung tvs and i can get the 1080p mpds but thts it
    Quote Quote  
  10. Do not send me DM's
    Join Date
    Dec 2021
    Location
    Tórshavn
    Search Comp PM
    Originally Posted by Dannyboi View Post
    So Anyone got a way to download and decrypt 1080p MY5 Content??
    Are you still at this?
    Right, Danny the samsung TV app is MSPR encrypted.
    MSPR is not bypassed, is not hacked and is not open.
    You will not get 1080p decryption of those streams.

    It is clearly and obviously beyond your abilities to even read the advice previously given to you.
    Quote Quote  
  11. Originally Posted by sorenb View Post
    Originally Posted by dannyboi View Post
    so anyone got a way to download and decrypt 1080p my5 content??
    are you still at this?
    Right, danny the samsung tv app is mspr encrypted.
    Mspr is not bypassed, is not hacked and is not open.
    You will not get 1080p decryption of those streams.

    It is clearly and obviously beyond your abilities to even read the advice previously given to you.
    stop talking no one will listen to u!!
    Quote Quote  
  12. Do not send me DM's
    Join Date
    Dec 2021
    Location
    Tórshavn
    Search Comp PM
    Originally Posted by Dannyboi View Post
    Originally Posted by sorenb View Post
    Originally Posted by dannyboi View Post
    so anyone got a way to download and decrypt 1080p my5 content??
    are you still at this?
    Right, danny the samsung tv app is mspr encrypted.
    Mspr is not bypassed, is not hacked and is not open.
    You will not get 1080p decryption of those streams.

    It is clearly and obviously beyond your abilities to even read the advice previously given to you.
    stop talking no one will listen to u!!
    I get the feeling you're merely a teenager. Well, I hope so, otherwise you seem to be both intellectually and emotionally stunted.
    You will not be able to decrypt the samsung tv app streams. It is not widevine encrypted it is MSPR (Microsoft Play Ready) encrypted.
    Now, just to aid in your lack of reading comprehension, let me restate that.
    You can not decrypt MSPR streams with widevine decryption tools. It CAN NOT happen. It is not possible.
    Quote Quote  
  13. post the 1080 mpd here and we will know if is WV or MSPR...

    Originally Posted by Dannyboi View Post
    Originally Posted by deccavox View Post
    Originally Posted by Dannyboi View Post
    So Anyone got a way to download and decrypt 1080p MY5 Content??
    You cannot get what ain't there in the first place
    it is there the My5 app streams in 1080p on samsung tvs and i can get the 1080p mpds but thts it
    Quote Quote  
  14. Member
    Join Date
    Feb 2022
    Location
    Europe
    Search PM
    They come from here: http://akasss.channel5.com/playready/
    so yes they are playready, there is no widevine in these mpd's

    edit:
    http://akasss.channel5.com/playready/C5318400001/C5318400001A/20200629142103/C53184000...Manifest_1080p for example
    Quote Quote  
  15. Member
    Join Date
    Dec 2021
    Location
    Scotland
    Search Comp PM
    Originally Posted by Diazole View Post
    Originally Posted by A_n_g_e_l_a View Post
    Originally Posted by Diazole View Post

    I've managed to figure out how to get the 5000kbps stream so i'll update the script once i've finished testing.
    Code:
        #wa ~worst-audio needed as channel4 ba downloads a narration audio version for visually impaired.
        os.system(f"yt-dlp --allow-u -f wa -o 'encryptAud.%(ext)s' {url}")
    I have this in my channel4 script that uses WKS-KEYS. It works.
    I don't think that's any better because you could potentially download a lower bit rate audio stream?

    The reason "ba" grabs the descriptive audio track is because yt-dlp sorts by lang to figure out the best audio. The descriptive stream has lang="en" whereas the normal stream does not.

    The correct way would be to make yt-dlp check the Role node as that contains whether the stream is descriptive or not, but I don't think yt-dlp supports that.

    Normal:
    Code:
    <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main" />
    Descriptive:
    Code:
    <Role schemeIdUri="urn:mpeg:dash:role:2011" value="description" />
    I know this is an old post now, but here goes. I'm using my own script for All4. Not quite as elegant as Diazole's method, but I didn't want to mess up my pywidevine for now that I use in all my webplayer solutions. I still use cURL to Python convertor, but use pyperclip to grab the clipboard contents. Anyway this is how I overcame the need to not grab the AD audio:

    Code:
    import subprocess
    
    ##### Determine audio reference
    com1 = 'yt-dlp --allow-u -F "{0}"'
    com = com1.format(mpd_url)
    
    p1 = subprocess.run(com,shell=True, capture_output=True, text=True)
    spec_list = p1.stdout
    print(spec_list)
    
    ##### find the correct audio
    index_audio = spec_list.find("audio=")
    full_audio = spec_list[index_audio:index_audio+12]
    print(f"audio ID chosen is {full_audio}")
    
    os.system(f'yt-dlp --allow-u -f bestvideo --downloader aria2c "{mpd_url}" -o encryptVid.mp4')
    os.system(f'yt-dlp --allow-u -f {full_audio} --downloader aria2c "{mpd_url}" -o encryptAud.m4a')
    Perhaps a bit long winded. But it works lol.
    Quote Quote  
  16. Do not send me DM's
    Join Date
    Dec 2021
    Location
    Tórshavn
    Search Comp PM
    You could simply take note of the audio track name
    "audio=128000"
    vs
    "audio_eng=128000"
    And noting which one corresponds to the audio descriptive track, and simply ignore it.
    Quote Quote  
  17. This was surprisingly simple to use:

    py -m pip install -r requirements.txt
    pywidevine create-device ...
    py c4-dl.py --download ...

    On windows I needed to manually create a download folder (no idea why, but the os call in the script to create it wasn't happy). Then it 'just works'.

    I've tried to figure out how the subtitle url is created, without success, so that part is manual (if anyone has the answer, please do share).
    Quote Quote  
  18. Do not send me DM's
    Join Date
    Dec 2021
    Location
    Tórshavn
    Search Comp PM
    Originally Posted by bamboobali View Post
    This was surprisingly simple to use:

    py -m pip install -r requirements.txt
    pywidevine create-device ...
    py c4-dl.py --download ...

    On windows I needed to manually create a download folder (no idea why, but the os call in the script to create it wasn't happy). Then it 'just works'.

    I've tried to figure out how the subtitle url is created, without success, so that part is manual (if anyone has the answer, please do share).
    subtitles
    Code:
    os.system(f'yt-dlp --allow-u --write-subs --skip-download "{mpd_url}" -o subs.vtt'
    then use subtitle edit to convert,
    subtitleedit /convert subs.vtt.und.vtt subrip

    you COULD use ffmpeg, but C4 subs have some blank spaces that kill the ffmpeg conversion
    but sed can remove the 2 blank lines
    Code:
    sed -i 2,2d subs.vtt.und.vtt
    Note, the sub fle name, sub.vtt.und.vtt is what yt-dlp will name the sub file when the using the -o flag with subs.vtt
    Quote Quote  
  19. Thanks, that works perfectly.
    Quote Quote  
  20. Member
    Join Date
    Dec 2020
    Location
    Croatia
    Search PM
    Originally Posted by achilles View Post
    1. Believe it or not, for some shows, the browser manifest actually contains higher bitrate streams than the android device manifest. So, ideally, the script should have a toggle to select either the browser or android manifest rather than ripping the old code out completely. Or even better, it tries both and finds the one with the highest bitrate but that's maybe more work than required. Ultimately, it's not a big deal, a person could just keep the old script lying around but it you make further edits in the future, it could cause a versioning problem.
    For me it happened on "Jake's Progress" so I'm guessing it's an issue on older shows like that which don't have a 5k bitrate option.

    EDIT: updated with code for both versions of the script and using subtitle edit for much better results
    For subtitles, this seems to do the trick for me:

    1. download subtitle edit, portable version: https://github.com/SubtitleEdit/subtitleedit/releases
    unzip contents into a dir called "SubtitleEdit"and copy it (not just the exe, the whole directory) into the script's "bin" folder

    2. inside the script itself add new global variables subs_exist and subs_url to the beginning and initially set to False and an empty string "", respectively

    3. in get_vod_stream:
    first add subs_exist and subs_url to the beginning of the function (right after try: ) as global vars so they can be modified:
    Code:
    global subs_exist, subs_url
    then:
    in the old script before "for field in resp['videoProfiles']:" add:
    Code:
    try:
        for i in resp['subtitlesAssets']:
            if (os.path.splitext(i['url'])[1] == ".vtt"):
                subs_url = i['url']
                subs_exist = True
    except Exception as e:
        print(f'Error getting subtitle: {e}')
        pass
    in the new script before "return vod_stream" add:
    Code:
    try:
        subtitles_element = root.find("assetInfo").find("subtitles")
        for sub in subtitles_element.iter():
            if (isinstance(sub.text, str) and os.path.splitext(sub.text)[1] == ".vtt"):
                subs_url = sub.text
                subs_exist = True
    except Exception as e:
         print(f'Error getting subtitle: {e}')
         pass
    4. write a new function for grabbing vtt, and converting to srt using subtitle edit:
    Code:
    def download_subs(output_title):
        res_sub = requests.get(subs_url)
    
        with open(f'downloads/{output_title}/{output_title}.vtt', 'w', encoding="utf-8") as f:
            f.write(res_sub.text)
    
        subprocess.run(
            f'"bin/SubtitleEdit/SubtitleEdit.exe" /convert "downloads/{output_title}/{output_title}.vtt" srt /removeformatting')
    5. and finally, add this to main() after merge_streams:
    Code:
    if (subs_exist is True):
        download_subs(output_title)

    thanks to sorenb, sipho and deccavox for tips on subtitle edit and of course diazole for the script
    Last edited by ampersand; 28th Jan 2023 at 05:34.
    Quote Quote  
  21. Member
    Join Date
    Dec 2022
    Location
    Lesotho
    Search Comp PM
    Originally Posted by ampersand;2678895

    it's not as elegant as Sorenb's 3 lines of code but it doesn't use [url=https://www.videohelp.com/software/Subtitle-Edit
    subtitle edit[/url] (which if I remember correctly when I last used it for vtt->srt conversion, keeps the text formatting of the vtt sub in the produced srt - text color and placement) or sed which I believe is a linux program that's missing on windows
    I've noticed that there will be a few empty lines in the resulting srt that weren't in the vtt, but not very often and it seems a small price to pay for a one click solution
    Subtitle Edit has a command line option to strip formatting and other nasties.
    Quote Quote  
  22. Do not send me DM's
    Join Date
    Dec 2021
    Location
    Tórshavn
    Search Comp PM
    Code:
    subtitleedit /help
    Subtitle Edit 3.6.10 - Batch converter
    
    - Usage: SubtitleEdit /convert <pattern> <name-of-format-without-spaces> [<optional-parameters>]
    
        pattern:
            one or more file name patterns separated by commas
            relative patterns are relative to /inputfolder if specified
        optional-parameters:
            /adjustduration:<ms>
            /deletecontains:<word>
            /ebuheaderfile:<file name>
            /encoding:<encoding name>
            /forcedonly
            /fps:<frame rate>
            /inputfolder:<folder name>
            /multiplereplace (equivalent to /multiplereplace:.)
            /multiplereplace:<comma separated file name list> ('.' represents the default replace rules)
            /ocrengine:<ocr engine> ("tesseract"/"nOCR")
            /offset:hh:mm:ss:ms
            /outputfilename:<file name> (for single file only)
            /outputfolder:<folder name>
            /overwrite
            /pac-codepage:<code page>
            /renumber:<starting number>
            /resolution:<width>x<height>
            /targetfps:<frame rate>
            /teletextonly
            /track-number:<comma separated track number list>
          The following operations are applied in command line order
          from left to right, and can be specified multiple times.
            /ApplyDurationLimits
            /FixCommonErrors
            /RemoveLineBreaks
            /MergeSameTimeCodes
            /MergeSameTexts
            /MergeShortLines
            /FixRtlViaUnicodeChars
            /RemoveUnicodeControlChars
            /ReverseRtlStartEnd
            /RemoveFormatting
            /RemoveTextForHI
            /ConvertColorsToDialog
            /RedoCasing
            /BalanceLines
    
        Example: SubtitleEdit /convert *.srt sami
        Show this usage message: SubtitleEdit /help
        List available formats: SubtitleEdit /help formats
    Quote Quote  
  23. Member
    Join Date
    Dec 2021
    Location
    Scotland
    Search Comp PM
    An example I used in some of my scripts:

    Code:
    os.system(f"SubtitleEdit /convert {srt_file} SubRip /overwrite /fixcommonerrors /removeformatting /removetextforhi")
    That strips the nasties.
    Clearly srt_file is the name of my selected srt file.

    Also, make sure SubtitleEdit.exe is defined in Environmental variables PATH.
    Quote Quote  
  24. Member
    Join Date
    Dec 2020
    Location
    Croatia
    Search PM
    thanks!
    Quote Quote  
  25. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    Code:
        with open(r"./subtitle.en.vtt", 'w') as f:
            # iterate each line
            for number, line in enumerate(lines):
                # list index starts from 0
                if number not in range(1,6):
                    f.write(line)
    This snippet removes a couple of lines from the subtitle file which causes all the errors with C4's subs.
    Quote Quote  
  26. psaframe
    Join Date
    Mar 2021
    Location
    Algeria
    Search PM
    Originally Posted by ampersand View Post
    Originally Posted by achilles View Post
    1. Believe it or not, for some shows, the browser manifest actually contains higher bitrate streams than the android device manifest. So, ideally, the script should have a toggle to select either the browser or android manifest rather than ripping the old code out completely. Or even better, it tries both and finds the one with the highest bitrate but that's maybe more work than required. Ultimately, it's not a big deal, a person could just keep the old script lying around but it you make further edits in the future, it could cause a versioning problem.
    For me it happened on "Jake's Progress" so I'm guessing it's an issue on older shows like that which don't have a 5k bitrate option.


    For subtitles, this seems to do the trick for me (in the new Diazole script, the old one works a bit differently because the subtitle element is named differently in the web mpd):

    (add new global variables subs_exist and subs_url to the beginning of the script and initially set to False and an empty string "", respectively)

    in get_vod_stream:
    first add subs_exist and subs_url to the beginning of the function (right after try: ) as global vars so they can be modified:
    Code:
    global subs_exist, subs_url
    then before "return vod_stream" add:
    Code:
    try:
        subtitles_element = root.find("assetInfo").find("subtitles")
        for sub in subtitles_element.iter():
            if (isinstance(sub.text, str) and os.path.splitext(sub.text)[1] == ".vtt"):
                subs_url = sub.text
                subs_exist = True
    except Exception as e:
         print(f'Error getting subtitle: {e}')
         pass
    write a new function for grabbing vtt, modifying it into something ffmpeg can handle and producing srt:
    Code:
    def download_subs(output_title):
        res_sub = requests.get(subs_url)
        res_sub = res_sub.text.split("\r\n")
    
        fixed = []
        for line in res_sub:
            if (line.startswith("::cue")):
                continue
            fixed.append(line + "\n")
    
        with open(f'downloads/{output_title}/{output_title}.vtt', 'w', encoding="utf-8") as f:
            f.writelines(fixed)
    
        subprocess.run(
            f'ffmpeg -loglevel warning -i "downloads/{output_title}/{output_title}.vtt" -c srt "downloads/{output_title}/{output_title}.srt"')
    and finally, add this to main() after merge_streams:
    Code:
    if (subs_exist is True):
                download_subs(output_title)

    it's not as elegant as Sorenb's 3 lines of code but it doesn't use subtitle edit (which if I remember correctly when I last used it for vtt->srt conversion, keeps the text formatting of the vtt sub in the produced srt - text color and placement) or sed which I believe is a linux program that's missing on windows
    I've noticed that there will be a few empty lines in the resulting srt that weren't in the vtt, but not very often and it seems a small price to pay for a one click solution

    i did like you said but eng sub don't downloaded, any help here woud be great
    Last edited by naim2007; 25th Jan 2023 at 13:30.
    Quote Quote  
  27. Member
    Join Date
    Dec 2020
    Location
    Croatia
    Search PM
    like I said, that's the old diazole script that works differently, it won't work there
    get the new one
    Quote Quote  
  28. psaframe
    Join Date
    Mar 2021
    Location
    Algeria
    Search PM
    Originally Posted by ampersand View Post
    like I said, that's the old diazole script that works differently, it won't work there
    get the new one
    My bad. I edited old one. Thanks for pointing me.
    Quote Quote  
  29. Member
    Join Date
    Dec 2020
    Location
    Croatia
    Search PM
    I will be reediting the code to replace my fumbling around editing the vtt into something parseable by ffmpeg with just using subtitle edit and will edit the post when I do
    I've already tried subtitle edit out on STV and it works well

    EDIT: done, post updated
    Last edited by ampersand; 28th Jan 2023 at 05:35.
    Quote Quote  
  30. Member
    Join Date
    Dec 2021
    Location
    Scotland
    Search Comp PM
    Here's my solution to an All4 downloader.

    If you haven't got them already you'll need uncurl and pyperclip modules (use pip install in the normal way).
    It's even easier to use than Diazole's and you don't have to install the pywidevine module. I think I've scripted it so it'll run on all platforms (Windows, linux, Mac). I've pinched bits of script from medvm's l3.py, so a big thank you there.

    Just drop this (I called it all4.py) into the WKS-KEYS folder. You don't need a header.py file.

    You'll need the likes of ffmpeg.exe, ffprobe.exe, mp4decrypt.exe, yt-dlp.exe, preferably set to run globally in Windows PATH or its equivalent (or put them in the same folder as this).

    Run: py all4.py.
    You'll get the prompt: Filter for wide (or acquire), do `Copy as cURL(cmd)` to get it on your clipboard NOTE: NOT `cURL(bash)` then press Enter to continue....

    That's the only input from you (apart from giving the final file a name). No more messing about with cURL to Python convertor. Just sit back and relax.
    Code:
    #### All4 version (20230207-1)
    """make sure you've done: pip install uncurl
       pip install pyperclip"""
    
    import requests
    import xmltodict, base64
    import json
    from pywidevine.L3.cdm import deviceconfig
    from base64 import b64encode
    from pywidevine.L3.decrypt.wvdecryptcustom import WvDecrypt
    from urllib.parse import urlparse
    import uncurl
    import pyperclip as PC
    import subprocess
    import os
    import shutil, glob
    
    ##########useful when used within VS Code to tell it which directory you're in
    abspath = os.path.abspath(__file__)
    dname = os.path.dirname(abspath)
    os.chdir(dname)
    ##########
    
    def cls():
        # posix is os name for Linux or mac
        if(os.name == 'posix'):
            os.system('clear')  # clear is the bash command
        # else screen will be cleared for windows (os name is actually nt for Windows)
        else:
            os.system('cls')  # cls is the batch command
    
    def cURL_cmd():
        wait = '''\n\n\n   Filter for wide (or acquire), do `Copy as cURL(cmd)` to get it on your clipboard     NOTE: NOT `cURL(bash)`\n   then press Enter to continue....'''
        input(wait)
        mycode = PC.paste()
        mycode = mycode.replace("^", "")
        context = uncurl.parse_context(mycode)
        lic_url = context.url
        myjson = json.loads(context.data)
        requestid = myjson['request_id']
        token = myjson['token']
        mpd_url = (myjson['video']['url'])
        headers = dict(context.headers)  #this is an OrderedDict
        return lic_url, requestid, mpd_url, headers, token
    
    def get_pssh(mpd_url, headers):
        pssh = ''
        kid=""
        r = requests.get(url=mpd_url,headers=headers)
        r.raise_for_status()
        xml = xmltodict.parse(r.text)
        mpd = json.loads(json.dumps(xml))
        
        try:
            def find_str(s, char):
                index = 0
    
                if char in s:
                    c = char[0]
                    for ch in s:
                        if ch == c:
                            if s[index:index+len(char)] == char:
                                return index
    
                        index += 1
    
                return -1
            teilifis =str(r.content)
            x=find_str(teilifis,"000000")
            stringy=str(r.content)
            y=x+36
            kid= stringy[x:y]
        except:
            pssh = input('Unable to find PSSH in mpd. Edit getPSSH.py or enter PSSH manually: ')
            
        def get_pssh(keyId):
            array_of_bytes = bytearray( b'\x00\x00\x002pssh\x00\x00\x00\x00')
            array_of_bytes.extend(bytes.fromhex("edef8ba979d64acea3c827dcd51d21ed"))
            array_of_bytes.extend(b'\x00\x00\x00\x12\x12\x10')
            array_of_bytes.extend(bytes.fromhex( keyId.replace("-", "")))
            return base64.b64encode(bytes.fromhex(array_of_bytes.hex()))
    
        kid = kid.replace('-', '')
        assert len(kid) == 32 and not isinstance(kid, bytes), "wrong KID length"    
        pssh = get_pssh(kid)
        
        if pssh == '':
            pssh = input(f'\nUnable to find PSSH. \nEdit getPSSH.py or enter PSSH manually: ')
            return pssh
        
        return pssh
    
    def WV_Function(pssh, lic_url, cert_b64=None):
    	wvdecrypt = WvDecrypt(init_data_b64=pssh, cert_data_b64=cert_b64, device=deviceconfig.device_android_generic)                   
    	raw_request = wvdecrypt.get_challenge()
    	request = b64encode(raw_request)
    	    
        #All4 support
    	responses.append(requests.post(url=lic_url, headers=headers, params=params,
    		json={
    		"request_id":requestid,
    		"token":token,
    		"video":{"type":"ondemand","url":mpd_url},
    		"message":str(request, "utf-8" ),
    		}))
    	
    	for idx, response in enumerate(responses):
    		if len(str(response.content, "utf-8")) > 500:
    			widevine_license = response
    			print(f'{chr(10)}license response status: {widevine_license}{chr(10)}')                                           
                		
    	lic_field_names = ['license', 'payload', 'getWidevineLicenseResponse']
    	lic_field_names2 = ['license']
    	
    	if str(widevine_license.content, 'utf-8').find(':'):
    		for key in lic_field_names:
    			try: 
    				license_b64 = json.loads(widevine_license.content.decode())[key]
    			except:
    				pass			
    			else:
    				for key2 in lic_field_names2:
    					try: 
    						license_b64 = json.loads(widevine_license.content.decode())[key][key2]
    					except:
    						pass
    	
    	wvdecrypt.update_license(license_b64)
    	Correct, keyswvdecrypt = wvdecrypt.start_process()
    	if Correct:
    		return Correct, keyswvdecrypt 	
    
    
    def filename():
        output_name = input("What do you want to call your final file? (do not include file .extension like .mp4) ")
        output_name = f"{output_name}.mp4"
        path = f"./Completed/{output_name}"
        # look to see if duplicate filename
        if os.path.isfile(path):
            print(f"\nyou already have a file called {output_name}. Choose another name\n")
            return filename()
        #look to see if any illegal characters in filename
        illegals = "@$%\/:*?\"<>|~`#^+=\{\};!"
        any_illegals = (set(output_name) & set(illegals))
        if not any_illegals:
            return output_name
        else:
            list_illegals = ' '.join(any_illegals)
            print(f"\nyou have included the following which are not legal characters:       {list_illegals}\n")
            return filename()
    #---------------------------------------------------------------------------------------------------------------
    
    cls()
    lic_url, requestid, mpd_url, headers, token = cURL_cmd()
    
    print(f"\n\nmpd_url is:    {mpd_url}")
    print(f"\nlicence is:      {lic_url}")
    print(f"\nrequest_id is:   {requestid}")
    print(f"\ntoken is:        {token}")
    
    responses = []
    license_b64 = ''
    pssh = get_pssh(mpd_url, headers)
    print(f"\nPSSH obtained is: {pssh.decode('utf-8')}")
    
    params = None
    params = urlparse(lic_url).query
    correct, keys = WV_Function(pssh, lic_url)
    
    # for key in keys:
    # 	print('KID:KEY -> ' + key)
    keys = str(keys[0])
    division = keys.find(":")
    key = (keys[division+1:])
    print(f"\n   KEY# is {key}")
    
    print("\n\n")
    
    ##### Determine audio reference
    com1 = 'yt-dlp --allow-u -F "{0}"'
    com = com1.format(mpd_url)
    
    p1 = subprocess.run(com,shell=True, capture_output=True, text=True)
    spec_list = p1.stdout
    print(spec_list)
    
    ##### find the correct audio
    index_audio = spec_list.find("audio=")
    full_audio = spec_list[index_audio:index_audio+12]
    print(f"audio ID chosen is {full_audio}")
    
    os.system(f'yt-dlp --allow-u -f bestvideo -N 6 "{mpd_url}" -o encryptVid.mp4')
    os.system(f'yt-dlp --allow-u -f {full_audio} -N 6 "{mpd_url}" -o encryptAud.m4a')
    
    
    print("==============================\n\n Decrypting\n\n==============================")
    
    os.system(f"mp4decrypt --show-progress --key 1:{key} encryptVid.mp4 video_decrypt.mp4")
    os.system(f"mp4decrypt --show-progress --key 1:{key} encryptAud.m4a audio_decrypt.m4a")
    
    if not os.path.exists("Throwaway"):
        os.makedirs("Throwaway")
    
    if not os.path.exists("Completed"):
        os.makedirs("Completed")
    
    cls()
    print("\n\n\n")
    
    output_name = filename()
    
    os.system(f"ffmpeg -i video_decrypt.mp4  -i audio_decrypt.m4a -c:v copy -c:a copy mux_file.mp4")
    os.rename("mux_file.mp4", f'{output_name}')
    
    shutil.move(f'{output_name}', "./Completed")
    
    for data in glob.glob("*_decrypt*.*"):
        shutil.move(data,"./Throwaway")
    for data in glob.glob("encrypt*.*"):
        shutil.move(data,"./Throwaway")
    shutil.rmtree("./Throwaway")
    
    print(f"All done.\n\n Your final file '{output_name}' is in 'Completed' folder")
    Have fun.
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!