Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Fetches a ChromeOS image for ARM and extracts the Widevine and Flash binaries, saving them in a compressed archive
#!/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
# 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"
tar -C"$MNTPNT" -caf "$ARCHIVE_NAME" opt/google/chrome/libwidevinecdm.so opt/google/chrome/pepper/libpepflashplayer.so --xform 's/pepper/PepperFlash/' --format ustar
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
# Inform the user how to proceed
cat <<EOF
To install the contents of these files on an ARMhf device, copy the tar archive over to the target machine and issue the following:
sudo tar -C/ -xf $ARCHIVE_NAME
EOF
@puccaso

This comment has been minimized.

Copy link

puccaso commented Nov 18, 2018

do we not need libwidevinecdmadapter.so for raspberry pi 3b?

@ruario

This comment has been minimized.

Copy link
Owner Author

ruario commented Nov 25, 2018

No, the adapter has not been needed for several Chromium versions now. So unless you are running an old Chromium, it should be fine.

@nrainbow

This comment has been minimized.

Copy link

nrainbow commented Dec 4, 2018

i try to install widevine in chromium V65 on a raspberry with raspian. The last step was '
sudo tar -C/ -xf widevine-flash-20181204_armhf.tgz'. What i must doing to check the install was successfully. When i try to view a video in www.netflix i get the error message 'Netflix-Systemvorausetzungen für HTML5-Player und Silverlight' .

@stuartmacgregor

This comment has been minimized.

Copy link

stuartmacgregor commented Dec 5, 2018

I ran the above script on my raspberry pi 3b and I now have libwidevinecdm.so in /opt/google/chrome (and also simlinked to vivaldi folder etc)
But spotify web player still doesn't work. What am I doing wrong?

@ruario

This comment has been minimized.

Copy link
Owner Author

ruario commented Dec 6, 2018

@nrainbow You need to change your user agent for Netflix to be a ChromeOS user agent

https://help.vivaldi.com/article/raspberry-pi/#netflix

I would also suggest you then delete any Netflix cookies before trying again.

@stuartmacgregor What is the architecture of the OS you are running. If ARM 32-Bit it will work. If ARM 64-Bit it will not work as the script is fetching from a ChromeOS image that is ARM 32-Bit, thus both libs are ARM 32-Bit. If you know of a source for for ARM 64-Bit Widevine I will update the script accordingly.

@stuartmacgregor

This comment has been minimized.

Copy link

stuartmacgregor commented Dec 7, 2018

Thanks a lot for the reply.

My OS is 32 bit
pi@raspberrypi:~ $ getconf LONG_BIT
32

Any other ideas on what's up would be much appreciated.

@alexb1995

This comment has been minimized.

Copy link

alexb1995 commented Dec 19, 2018

Same for me with Spotify, it loads up totally fine, but when I try to play a song I get the error (Translated:) "Something went wrong with this playlist".
Did you anyone find a solution?

@ogerardin

This comment has been minimized.

Copy link

ogerardin commented Jan 6, 2019

I'm at the same point as stuartmacgregor...
What's bothering me is that Widevine doesn't even appear in chrome://components
The symlink is present in /opt/vivaldi and points to the correct location /opt/google/chrome/libwidevinecdm.so but that doesn't seem to be enough...

@lentschi

This comment has been minimized.

Copy link

lentschi commented Jan 12, 2019

@ruario @ogerardin
Yeah, for me it's not working either. Opening https://bitmovin.com/demos/drm shows that widevine is not available.

When running lsof /opt/vivaldi/libwidevinecdm.so i see that at least the linked so file is loaded, but vivaldi throws no error indicating why the plugin fails:

COMMAND    PID USER  FD   TYPE DEVICE SIZE/OFF   NODE NAME
vivaldi-b 9208   pi mem    REG  179,2  8213180 516659 /opt/google/chrome/libwidevinecdm.so
vivaldi-b 9210   pi mem    REG  179,2  8213180 516659 /opt/google/chrome/libwidevinecdm.so
vivaldi-b 9275   pi mem    REG  179,2  8213180 516659 /opt/google/chrome/libwidevinecdm.so
vivaldi-b 9292   pi mem    REG  179,2  8213180 516659 /opt/google/chrome/libwidevinecdm.so
vivaldi-b 9642   pi mem    REG  179,2  8213180 516659 /opt/google/chrome/libwidevinecdm.so
vivaldi-b 9729   pi mem    REG  179,2  8213180 516659 /opt/google/chrome/libwidevinecdm.so

Maybe it's because plugin support has ended or changed (?) since Chrome/Chromium 57?: https://www.howtogeek.com/303934/what-happened-to-chrome-plugins-in-google-chrome/

These two solutions work for me with an up-to-date raspbian stretch:

  1. https://github.com/nateg5/Android/blob/master/NateCast/README.md -> Makes it run within an older version of Chromium (56). When doing a first test, performance seemed to be pretty poor though... I still need to figure out, if this was a coincidence (network issue...) or if it's always like this. Am I right with my above assumption and this cannot be done with Chrome >= 57? (Then this method would be doomed.)
  2. (Netflix ONLY) https://github.com/asciidisco/plugin.video.netflix -> Running this (requires kodi 18 & also check the other prerequisites in the README!) seems to perform better (Especially after increasing the GPU memory a bit).
    However on my projector sequences, where there's a lot of movement, still seem a bit more blurry than when playing from a Windows 10 firefox with a proper graphics card. If I read this right, there's hope though as inputstream.adaptive is still being actively developed: asciidisco/plugin.video.netflix#27
@Brunoarndt

This comment has been minimized.

Copy link

Brunoarndt commented Apr 5, 2019

i run this script and the last step was "sudo tar -C/ -xf widevine-flash-20190404_armhf.tgz" but i I do not know what to do now

@businessBoris

This comment has been minimized.

Copy link

businessBoris commented Apr 25, 2019

@Brunoarndt , did you complete this last step? You didn't actually say.

@ruario , [Pi Zero W armhf] LibreELEC gives me a read-only fs and I'm stuck. Hints appreciated. I know Netflix will run on a zero, one only has to query youtube.

@cryonicblue

This comment has been minimized.

Copy link

cryonicblue commented Jun 6, 2019

This just give me a "/bin/sh: 0: Illegal option -"

@ruario

This comment has been minimized.

Copy link
Owner Author

ruario commented Aug 28, 2019

@Brunoarndt You copy the widevine-flash-*_armhf.tgz file to your arm device and issue the command there.

@ruario

This comment has been minimized.

Copy link
Owner Author

ruario commented Aug 28, 2019

@cryonicblue on what distro did you run it?

@ruario

This comment has been minimized.

Copy link
Owner Author

ruario commented Aug 28, 2019

@businessBoris run the script on a different device. Not your ARM device, then copy the created archive over.

P.S. Youtube does not use Widevine.

@ruario

This comment has been minimized.

Copy link
Owner Author

ruario commented Aug 28, 2019

@ogerardin Widevine doesn't appear in chrome://components on any Linux based device. Even Chrome on x86_64. You will only see it under chrome://components on Windows or macOS

@ruario

This comment has been minimized.

Copy link
Owner Author

ruario commented Aug 28, 2019

@nrainbow for netflix you will need a ChromeOS UA

https://help.vivaldi.com/article/raspberry-pi/#netflix

@ruario

This comment has been minimized.

Copy link
Owner Author

ruario commented Aug 28, 2019

Best bet for testing is to load https://bitmovin.com/demos/drm and check if widevine is marked as enabled and also to try and load the examples marked DRM on https://demo.castlabs.com

Remember that you will also need a Chromium patched FFMpeg to play H.264, e.g.

https://launchpadlibrarian.net/435404265/chromium-codecs-ffmpeg-extra_76.0.3809.87-0ubuntu0.16.04.1_armhf.deb

@ruario

This comment has been minimized.

Copy link
Owner Author

ruario commented Aug 30, 2019

Ok, I just checked this all again. Ran the script on Ubuntu 18.04 to create the archive and then transferred the archive to Raspbian GNU/Linux 9 (stretch), running on a Pi. Installed it and I have working Widevine and Flash when using the latest Vivaldi snapshot (1649.4 [based on Chromium 77]).

@zhuhellozhu

This comment has been minimized.

Copy link

zhuhellozhu commented Oct 24, 2019

hello @ruario,

I follow your steps, and finally find out that drm tests pass but netflix falied, error M7121-1331.
Steps:
1.Run pi at Raspbian Stretch .
2.Run script to fetch widevine files and install at /opt/google/chrome
3.Install vivaldi 1694.4(and tested newest version too,based on chromium 78 )
4.install ua switcher and change ua string.
5.run drm demos testing, passed.can play video
6.play netflix, get a streaming error of M7121-1331.

any idea about this?

@ruario

This comment has been minimized.

Copy link
Owner Author

ruario commented Oct 24, 2019

@zhuhellozhu Yeah it needs adapting for Chromium 78 as the location for where widevine is expected to be placed is different. Even though I want to avoid maintaining this I know what the issue is and will likely try and fix it in the next couple of days. Thanks for the reminder

@tompreston

This comment has been minimized.

Copy link

tompreston commented Oct 25, 2019

Is there an official outlet for ARM libwidevinecdm.so? Extracting it from ChromeOS seems like a strange way to do it!

@ruario

This comment has been minimized.

Copy link
Owner Author

ruario commented Oct 25, 2019

@tompreston I do it this way because there is no official ARM libwidevinecdm.so. That is the problem!

@Zerthick

This comment has been minimized.

Copy link

Zerthick commented Nov 10, 2019

@ruario Until you update the script, what is the expected location now? Widevine has broken on Vivaldi now and I'm not sure where libwidevinecdm.so should be placed to fix it. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.