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
Results 61 to 90 of 124
Thread
-
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 . . .
-
-
@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. -
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 itLast edited by Dannyboi; 3rd Jan 2023 at 15:03.
-
-
-
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. -
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. -
-
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 -
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')
-
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. -
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'
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
-
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
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
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
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')
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 scriptLast edited by ampersand; 28th Jan 2023 at 05:34.
-
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 -
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
-
An example I used in some of my scripts:
Code:os.system(f"SubtitleEdit /convert {srt_file} SubRip /overwrite /fixcommonerrors /removeformatting /removetextforhi")
Clearly srt_file is the name of my selected srt file.
Also, make sure SubtitleEdit.exe is defined in Environmental variables PATH. -
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)
-
Last edited by naim2007; 25th Jan 2023 at 13:30.
-
like I said, that's the old diazole script that works differently, it won't work there
get the new one -
-
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 updatedLast edited by ampersand; 28th Jan 2023 at 05:35.
-
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")
Similar Threads
-
Y2Mate.ch Downloader Youtube
By jimwnola in forum Video Streaming DownloadingReplies: 25Last Post: 1st Jun 2022, 11:58 -
ITVHUB downloader?
By bal2001bc in forum Video Streaming DownloadingReplies: 6Last Post: 24th Jun 2021, 08:32 -
Shudder downloader?
By throwawayjz1 in forum Video Streaming DownloadingReplies: 1Last Post: 25th Jan 2021, 16:31 -
Using TV downloader
By frankopstaele in forum Newbie / General discussionsReplies: 0Last Post: 2nd Feb 2019, 19:44 -
Downmixing 6 channel AAC to 2 channel?
By bizzybody in forum Video ConversionReplies: 33Last Post: 12th Nov 2017, 11:19