Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encrypted playlist.m3u8 and video.m3u8 (not the content, just the m3u8) #395

Open
divStar opened this issue Jan 29, 2025 · 2 comments
Open

Comments

@divStar
Copy link

divStar commented Jan 29, 2025

Hello and thank you for making this library!

I am currently looking into parsing some m3u8 files, but these playlist.m3u8 and video.m3u8 files are encrypted.
I do have the encryption key and the GET requests return the IV and the encrypted playlist in the format: <IV hex>:<encrypted m3u8 data hex>.

I have manually decrypted the playlist using basically something like this:

        try:
            # Split the hex string by colon
            iv_hex, encrypted_data_hex = encrypted_hex.split(":")

            # Convert hex strings to bytes
            self.iv = bytes.fromhex(iv_hex)
            encrypted_data = bytes.fromhex(encrypted_data_hex)
            encryption_key = bytes.fromhex(self.encryption_key_hex)

            # Initialize AES cipher in CBC mode
            cipher = AES.new(encryption_key, AES.MODE_CBC, self.iv)

            # Decrypt and unpad the data
            decrypted_data = unpad(cipher.decrypt(encrypted_data), AES.block_size)

            # Decode to string
            self.decrypted_content = decrypted_data.decode("utf-8")
            return self.decrypted_content

        except Exception as e:
            print(f"Error decrypting data: {e}")
            return None

and while I can keep using it, it would be nice if m3u8 supported this sort of thing via load?

BTW: the content of the site I am getting this from is not DRM protected; it's just the playlist.m3u8 and video.m3u8 that is.

If this discussion is not allowed here, feel free to delete my issue.

Thank you!

@bbayles
Copy link
Contributor

bbayles commented Jan 29, 2025

I've run into this as well, but I think playlist decryption should be out of scope for this library — it would require a binary dependency, which would be a big shift. Also, encrypted playlist is not part of the 8216 RFC (whereas encrypted segments are).

@divStar
Copy link
Author

divStar commented Jan 29, 2025

Yeah, I understand that and in my script I already worked around it by decrypting it and then using m3u8.loads.

Perhaps it'd be possible to allow a custom function (e.g. preprocess_downloaded_playlist_func), which - if set (and None by default) would let a developer preprocess the downloaded data before it is parsed (e.g. in

self.data = parse(content, strict, custom_tags_parser)
) by the library?

This would allow me to write one decryption function, that takes the content, splits it by the colon and decrypts the second argument, ultimately setting it as the actual content.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants