Skip to content

Instantly share code, notes, and snippets.

@maxwelleite
Forked from neelshearer/latest-widevine.sh
Created April 4, 2018 19:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maxwelleite/2f840ceafc8149b58ca6cfe2830ff8ff to your computer and use it in GitHub Desktop.
Save maxwelleite/2f840ceafc8149b58ca6cfe2830ff8ff to your computer and use it in GitHub Desktop.
Depending on architecture, either grabs last 32-bit Widevine from chromium or fetches Chrome and extracts out Widevine so that it can be used by Vivaldi. Also works with other Chromium-based browsers, see guide below.
#!/usr/bin/env bash
available () {
command -v $1 >/dev/null 2>&1
}
# Make sure we have wget or curl
if available wget; then
SILENT_DL="wget -qO-"
LOUD_DL="wget"
elif available curl; then
SILENT_DL="curl -s"
LOUD_DL="curl -O"
else
echo "Install wget or curl" >&2
exit 1
fi
# Check which Chrome stream the user selected to fetch from
CHROME_STREAM=stable
while [ 0 ]; do
if [ "$1" = "-u" -o "$1" = "--unstable" ]; then
CHROME_STREAM=unstable
shift 1
elif [ "$1" = "-b" -o "$1" = "--beta" ]; then
CHROME_STREAM=beta
shift 1
else
break
fi
done
# Set Output dir
WIDEVINE_INSTALL_DIR=${WIDEVINE_INSTALL_DIR:-/opt/google/chrome}
# Set temp dir
TMP=${TMP:-/tmp}
# Set staging dir
STAGINGDIR=$TMP/widevine-staging
# Work out the latest stable Google Chrome if VERSION is unset
VERSION=$($SILENT_DL https://dl.google.com/linux/direct/google-chrome-${CHROME_STREAM}_current_x86_64.rpm | head -c96 | strings | rev | awk -F"[:-]" '/emorhc/ { print $2 }' | rev)
# Error out if $VERISON is unset, e.g. because previous command failed
if [ -z $VERSION ]; then
echo "Could not work out the latest version; exiting" >&2
exit 1
fi
# Don't start repackaging if the same version is already installed
if [ -e "$WIDEVINE_INSTALL_DIR/chrome-version-$VERSION" ] ; then
echo "The latest Widevine is already installed"
exit 0
fi
# If the staging directory is already present from the past, clear it down
# and re-create it.
if [ -d "$STAGINGDIR" ]; then
rm -fr "$STAGINGDIR"
fi
set -e
mkdir -p "$STAGINGDIR"
cd "$STAGINGDIR"
# Now get the rpm -
ARCH=$(arch)
if [ "$ARCH" = "i686" ]; then
echo ""
echo "32-bit system detected - downloading 32-bit widevine version directly from sourceforge"
echo ""
$LOUD_DL https://iweb.dl.sourceforge.net/project/lxpup/Other/chromium/widevine/chromium-widevine-plugin-48.0.2564.97-i386-1alien.txz
echo "Extracting Widevine from the archive ..."
tar xvf chromium-widevine-plugin-48.0.2564.97-i386-1alien.txz usr/lib/chromium/libwidevinecdm.so --xform='s#^.+/##x'
rm chromium-widevine-plugin-48.0.2564.97-i386-1alien.txz
else
echo ""
echo "64-bit system detected - downloading latest google chrome version and extracting file"
echo ""
$LOUD_DL https://dl.google.com/linux/direct/google-chrome-${CHROME_STREAM}_current_x86_64.rpm
DOWNLOADVERSION=$(head -c96 "google-chrome-${CHROME_STREAM}_current_x86_64.rpm" | strings | rev | awk -F"[:-]" '/emorhc/ { print $2 }' | rev)
if [ ! "$VERSION" = "$DOWNLOADVERSION" ]; then
echo "The version downloaded ($DOWNLOADVERSION) is different from the version expected ($VERSION)" >&2
exit 1
fi
# Extract the contents of the Google Chrome binary package
RPMHDRLGTH=$(grep -Fabom1 7zXZ google-chrome-${CHROME_STREAM}_current_x86_64.rpm)
echo "Extracting Widevine from the Chrome RPM ..."
tail -c+${RPMHDRLGTH%:*} google-chrome-${CHROME_STREAM}_current_x86_64.rpm | xz -d | cpio --quiet -id "./opt/google/chrome*/libwidevinecdm.so"
cd opt/google/chrome*
# Add version number file
touch "chrome-version-$VERSION"
fi
# Escalate privileges if needed and copy files into place
if [ "$UID" = 0 ]; then
mkdir -p "$WIDEVINE_INSTALL_DIR"
cp * "$WIDEVINE_INSTALL_DIR"
elif [ -r /etc/os-release ] && grep -qx 'ID=\(ubuntu\|linuxmint\)' /etc/os-release; then
echo "Calling sudo ... If prompted, please enter your password so Widevine can be copied into place"
sudo mkdir -p "$WIDEVINE_INSTALL_DIR"
sudo cp * "$WIDEVINE_INSTALL_DIR"
else
echo "Please enter your root password so Widevine can be copied into place"
su -c "sh -c \"mkdir -p $WIDEVINE_INSTALL_DIR && cp * $WIDEVINE_INSTALL_DIR\""
fi
# Tell the user we are done
echo "Widevine installed into $WIDEVINE_INSTALL_DIR"

Damn you 32-bit!

ruario built this incredible script and it didn't work for me - it took me far too long to work out why, but the 64-bit verion of libwidevinecdm.so will not work on a 32-bit system. This edit grabs the last 32-bit version of widevine (2016) from the chromium project and uses that instead if it detects a 32-bit system. Enjoy!

Summary

A bunch of people asked how they could use this script with pure Chromium on Ubuntu. The following is a quick guide. Though I still suggest you at least try Vivaldi. Who knows, you might like it. Worried about proprietary componants? Remember that libwidevinecdm.so is a binary blob you are taking from Chrome, so by following this guide you will have already made your distro less "pure". Also all our additions to the Chromium base are open source and our UI, while not open, is written in HTML/CSS/JS. Thus you can see exactly what we are doing (no funny business).

If you still want to run Chromium, the following explains how it is done.

Chromium setup

  • Install the package "chromium-codecs-ffmpeg-extra" to provide H.264/MP4 support (used by videos on Netflix). After install, you need to restart Chromium. You can confirm that it is installed and working correctly by going to http://www.quirksmode.org/html5/tests/video.html and checking that the first video listed plays.

  • Next run the script (latest-widevine.sh). This will create the file "libwidevinecdm.so" in "/opt/google/chrome".

  • Replace the "libwidevinecdm.so" provided by Chromium with a symlink to the file from Chrome:

sudo ln -fs /opt/google/chrome/libwidevinecdm.so /usr/lib/chromium-browser/libwidevinecdm.so 

Note: The path is typically "/usr/lib64/chromium/lib/libwidevinecdm.so" on non Debian/Ubuntu based distros.

You can confirm that DRM'd H.264/MP4 content is now playable by going to http://demo.castlabs.com/ and trying some of the demos.

Damn you Netflix!

The final complication is that Netflix does not expect pure Chromium to be able to be able play videos and hence they do a stupid thing. If they detect that Chromium is accesing a video, they point you to install Silverlight! This is particularly dumb because: you are running Linux (no Silverlight); Silverlight is an NPAPI plugin and Chrom(e|ium) only supports PPAPI. You will need to work around this.

  • Delete any cookies or data associated with Netflix. If you have failed to play videos once, then Netflix stores information about this in a cookie and you won't be able to play vidoes, even once your system is now correctly configured. Another "WTF‽" moment from the Netflix team.

  • Via a user agent editing extention or by starting Chromium with the -user-agent switch, remove the reference to "Ubuntu Chromium/XX.0.XXXX.XX", e.g.

/usr/lib/chromium-browser/chromium-browser --user-agent='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36'

Note: An extenstion is best otherwise you will need to start Chromium from the command line every time or edit the .desktop file to include this switch.

One final point. Every time Chromium upgrades it will replace the libwidevinecdm.so symlink with its own file. Thus you will need to remove it and re-create the symlink. I would also suggest re-running latest-widevine.sh at that point, to check for new versions and upgrade if needed.

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