Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
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 '' 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 ./

Check out this tutorial:

#!/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"
echo "Install Wget or cURL" >&2
exit 1
# Find a URL to a suitable armhf ChromeOS recovery image
CHROMEOS_URL="$($DL_SL | grep -A11 CB5-312T | sed -n 's/^url=//p')"
CHROMEOS_IMG="$(basename "$CHROMEOS_URL" .zip)"
if [ -e "$CHROMEOS_IMG" ]; then
# Fetch the recovery image (2Gb+ on disk after download)
# 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)"
mount -o ro "${LOOPD}p3" "$MNTPNT"
# 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"
# Note the mount point in a variable
MNTPNT="$(lsblk -lo MOUNTPOINT "${LOOPD}p3" | tail -n1)"
# Copy over files and make manifest
CHRFILES="$(mktemp -d -t ChromeOS_Files.XXXXXX)"
install -Dm644 "$MNTPNT"/opt/google/chrome/pepper/ "$CHRFILES"/
install -Dm644 "$MNTPNT"/opt/google/chrome/ "$CHRFILES"/
WVVER="$(grep -Eaom1 '([0-9]+\.){3}[0-9]+' "$CHRFILES"/"
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"/
chmod 755 "$CHRFILES"/
tar -C"$CHRFILES" -caf "$ARCHIVE_NAME" manifest.json --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"
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"
if [ "$DEL_IMG" = "N" ] || [ "${1:-EMPTY}" = "-k" ]; then
# Installing DRM support
echo "Installing DRM support for Chromium"
# check 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"'
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 /opt/WidevineCdm/_platform_specific/linux_arm
sudo mv /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
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. 🙏

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:, 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.

Copy link

lemariva commented Oct 18, 2020

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.

Copy link

edurenye commented Oct 19, 2020

Can't we get it from Ubuntu instead? It supports arm64.
Or from Android maybe?

Copy link

lemariva commented Oct 19, 2020

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

Copy link

edurenye commented Oct 21, 2020

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