Skip to content

Instantly share code, notes, and snippets.

@lemariva
Forked from ruario/1-README.md
Last active January 7, 2022 22:07
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save lemariva/0eb4ff4e847700627a5ebb71711c31bf to your computer and use it in GitHub Desktop.
Save lemariva/0eb4ff4e847700627a5ebb71711c31bf to your computer and use it in GitHub Desktop.
A script that fetches a ChromeOS image for ARM32 and extracts the Widevine and Flash binaries, saving them in a compressed archive for use with Chromium for DRM

The included script 'widevine-flash_armhf.sh' fetches a ChromeOS image for ARM and extracts the Widevine and Flash binaries, saving them in a compressed archive. Since it downloads a fairly large file (2Gb+ on disk after download) it is recommended that you run the script on a raspberry that has plenty of disk space.

The files in the compressed archive are copied to the folder /usr/lib/chromium-browser/ To run the file just type the following:

sudo ./widevine-flash_armhf.sh

Check out this tutorial: https://lemariva.com/blog/2020/06/raspberry-pi-amazon-prime-netflix-and-drm-solution

#!/bin/sh -eu
# Make sure we have wget or curl
available () {
command -v "$1" >/dev/null 2>&1
}
if available wget; then
DL="wget -O-"
DL_SL="wget -qO-"
elif available curl; then
DL="curl -L"
DL_SL="curl -s"
else
echo "Install Wget or cURL" >&2
exit 1
fi
# Find a URL to a suitable armhf ChromeOS recovery image
CHROMEOS_URL="$($DL_SL https://dl.google.com/dl/edgedl/chromeos/recovery/recovery.conf | grep -A11 CB5-312T | sed -n 's/^url=//p')"
CHROMEOS_IMG="$(basename "$CHROMEOS_URL" .zip)"
if [ -e "$CHROMEOS_IMG" ]; then
CHROMEOS_IMG_PATH="./"
DEL_IMG=N
else
CHROMEOS_IMG_PATH="$(mktemp -td ChromeOS-IMG.XXXXXX)"
DEL_IMG=Y
# Fetch the recovery image (2Gb+ on disk after download)
$DL "$CHROMEOS_URL" | zcat > "$CHROMEOS_IMG_PATH/$CHROMEOS_IMG"
fi
# Note the next free loop device in a variable
LOOPD="$(losetup -f)"
# If root, we can mount silently (no popup windows after mount)
if [ "$USER" = "root" ]; then
MNTPNT="$(mktemp -d -t ChromeOS.XXXXXX)"
losetup -Pf "$CHROMEOS_IMG_PATH/$CHROMEOS_IMG"
mount -o ro "${LOOPD}p3" "$MNTPNT"
else
# Associate all the partitions on the disk image with loop devices:
udisksctl loop-setup -rf "$CHROMEOS_IMG_PATH/$CHROMEOS_IMG"
sleep 1
# Mount the third partition of the disk image (if the previous did not do it automatically)
if ! lsblk -lo MOUNTPOINT "${LOOPD}p3" | tail -n1 | grep -q \.; then
udisksctl mount -b "${LOOPD}p3"
fi
# Note the mount point in a variable
MNTPNT="$(lsblk -lo MOUNTPOINT "${LOOPD}p3" | tail -n1)"
fi
# Copy over files and make manifest
CHRFILES="$(mktemp -d -t ChromeOS_Files.XXXXXX)"
install -Dm644 "$MNTPNT"/opt/google/chrome/pepper/libpepflashplayer.so "$CHRFILES"/libpepflashplayer.so
install -Dm644 "$MNTPNT"/opt/google/chrome/libwidevinecdm.so "$CHRFILES"/libwidevinecdm.so
WVVER="$(grep -Eaom1 '([0-9]+\.){3}[0-9]+' "$CHRFILES"/libwidevinecdm.so)"
WVMGR="$(echo $WVVER | cut -d. -f1)"
WVMIN="$(echo $WVVER | cut -d. -f2)"
echo "{\"version\":\"$WVVER\",\"x-cdm-codecs\":\"vp8,vp9.0,avc1,av01\",\"x-cdm-host-versions\":\"$WVMIN\",\"x-cdm-interface-versions\":\"$WVMIN\",\"x-cdm-module-versions\":\"$WVMGR\"}" > "$CHRFILES"/manifest.json
# Extract the libs out and copy them to a compressed tar archive
ARCHIVE_NAME="widevine-flash-$(date '+%Y%m%d')_armhf.tgz"
echo "Extracting and compressing files"
chmod 755 "$CHRFILES"/libpepflashplayer.so
chmod 755 "$CHRFILES"/libwidevinecdm.so
tar -C"$CHRFILES" -caf "$ARCHIVE_NAME" manifest.json libwidevinecdm.so libpepflashplayer.so --format ustar --owner 0 --group 0
rm -r "$CHRFILES"
echo "Created: $ARCHIVE_NAME"
# Cleanup
if [ "$USER" = "root" ]; then
umount "$MNTPNT"
losetup -d "$LOOPD"
rmdir "$MNTPNT"
else
ALLMNTS="$(lsblk -lo NAME,MOUNTPOINT "$LOOPD" | sed -n '/\//s/^\(loop[0-9]\+p[0-9]\+\).*/\1/p')"
echo "$ALLMNTS" | xargs -I{} -n1 udisksctl unmount -b /dev/{}
if [ "$LOOPD" != "$(losetup -f)" ]; then
udisksctl loop-delete -b "$LOOPD"
fi
fi
if [ "$DEL_IMG" = "N" ] || [ "${1:-EMPTY}" = "-k" ]; then
:
else
rm "$CHROMEOS_IMG_PATH/$CHROMEOS_IMG"
rmdir -v "$CHROMEOS_IMG_PATH"
fi
# Installing DRM support
echo "Installing DRM support for Chromium"
# check https://www.whatismybrowser.com/guides/the-latest-user-agent/chrome for the last version of the browsers
USER_AGENT='--user-agent="Mozilla/5.0 (X11; CrOS armv7l 13099.85.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.110 Safari/537.36"'
tar xf $ARCHIVE_NAME
mkdir -p ${HOME}/.config/chromium-browser/WidevineCdm
sudo mkdir -p /opt/WidevineCdm/_platform_specific/linux_arm
echo '{"Path":"/opt/WidevineCdm"}' > ${HOME}/.config/chromium-browser/WidevineCdm/latest-component-updated-widevine-cdm
sudo mv manifest.json /opt/WidevineCdm
sudo mv libwidevinecdm.so /opt/WidevineCdm/_platform_specific/linux_arm
sudo mv libpepflashplayer.so /usr/lib/chromium-browser/
# Changing user-agent to Chromium
cp /usr/share/applications/chromium-browser.desktop .
sed 's/Chromium/Chromium (DRM)/g' chromium-browser.desktop > chromium-drm-browser.desktop
sed -i 's@Exec=chromium-browser %U@'"Exec=chromium-browser %U $USER_AGENT"'@' chromium-drm-browser.desktop
sed -i 's@Exec=chromium-browser@'"Exec=chromium-browser $USER_AGENT"'@' chromium-drm-browser.desktop
sed -i 's@Exec=chromium-browser --temp-profile@'"Exec=chromium-browser --temp-profile $USER_AGENT"'@' chromium-drm-browser.desktop
sed -i 's@Exec=chromium-browser --incognito@'"Exec=chromium-browser --incognito $USER_AGENT"'@' chromium-drm-browser.desktop
sudo mv chromium-drm-browser.desktop /usr/share/applications/
# Clean up installation
#rm chromium-browser.desktop
rm $ARCHIVE_NAME
@rowen77
Copy link

rowen77 commented Jul 5, 2020

Got this working on a Pi4 8GB now able to watch the Formula 1 coverage on Channel 4 in the UK.
Thank you. 🙏

@edurenye
Copy link

edurenye commented Oct 1, 2020

Hi, I tried on a Raspberry Pi 4 with Raspberry Pi OS 64bit, and it does not work, I had to adapt it a bit forking your repo (see: https://gist.github.com/edurenye/4065b1294829d8fb890cce2fc0092c36), but I just got to fix the USER-AGENT, when I go to chrome://components in the browser I do not see the 'Widevine Content Decryption Module' component. It is in the folder, but Chromium does not load it.

@lemariva
Copy link
Author

I've removed the file for OS 64bit. You can change the --user-agent using the extension Custom User Agent String. But, I checked that the User ABI for all Chromium-OS is 32 bits (arm) (check out here), and the libraries don't load on Raspberry OS because the User ABI is 64bits. You'll get the following error: wrong ELF class: ELFCLASS32. I thought the information on the website wasn't correct and I checked 3 different images and I got the same error.

@edurenye
Copy link

Can't we get it from Ubuntu instead? https://packages.ubuntu.com/focal/chromium-browser It supports arm64.
Or from Android maybe?

@lemariva
Copy link
Author

Chromium per default doesn't include support for DRM (neither under Ubuntu). That means, you need Chrome, not Chromium and that's not available.

@edurenye
Copy link

I see 😞
And can't we get it from Android? In Android, Chrome is compiled for arm64, right?
But I guess might be difficult to get that from an apk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment