diff --git a/docs/development/upgrading-chrome.md b/docs/development/upgrading-chrome.md index 5cb9337cd09c..6e47a8b4f521 100644 --- a/docs/development/upgrading-chrome.md +++ b/docs/development/upgrading-chrome.md @@ -45,6 +45,46 @@ Chrome/Node API changes. - 64-bit Linux - ARM Linux +## Verify ffmpeg Support + +Electron ships with a version of `ffmpeg` that includes proprietary codecs by +default. A version without these codecs is built and distributed with each +release as well. Each Chrome upgrade should verify that switching this version is +still supported. + +You can verify Electron's support for multiple `ffmpeg` builds by loading the +following page. It should work with the default `ffmpeg` library distributed +with Electron and not work with the `ffmpeg` library built without proprietary +codecs. + +```html + + + + + Proprietary Codec Check + + +

Checking if Electron is using proprietary codecs by loading video from http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4

+

+ + + + +``` + ## Links - [Chrome Release Schedule](https://www.chromium.org/developers/calendar) diff --git a/script/cibuild b/script/cibuild index 92dec9db2dee..dc2d9d081045 100755 --- a/script/cibuild +++ b/script/cibuild @@ -91,6 +91,7 @@ def main(): run_script('build.py', ['-c', 'D']) if PLATFORM == 'win32' or target_arch == 'x64': run_script('test.py', ['--ci']) + run_script('verify-ffmpeg.py') def run_script(script, args=[]): diff --git a/script/lib/config.py b/script/lib/config.py index 94109bdbb231..d033d8a41c6a 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -9,7 +9,7 @@ import sys BASE_URL = os.getenv('LIBCHROMIUMCONTENT_MIRROR') or \ 'https://s3.amazonaws.com/github-janky-artifacts/libchromiumcontent' LIBCHROMIUMCONTENT_COMMIT = os.getenv('LIBCHROMIUMCONTENT_COMMIT') or \ - 'dd95b11e52f1e5596184d83d91c91d7b089d05f6' + '8d551064d2b3d11f89ce8d5c4610f34e0408bad8' PLATFORM = { 'cygwin': 'win32', diff --git a/script/verify-ffmpeg.py b/script/verify-ffmpeg.py new file mode 100755 index 000000000000..9d9dba067030 --- /dev/null +++ b/script/verify-ffmpeg.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python + +import os +import shutil +import subprocess +import sys + +from lib.util import electron_gyp, rm_rf + + +SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) +FFMPEG_LIBCC_PATH = os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor', + 'download', 'libchromiumcontent', 'ffmpeg') + +PROJECT_NAME = electron_gyp()['project_name%'] +PRODUCT_NAME = electron_gyp()['product_name%'] + + +def main(): + os.chdir(SOURCE_ROOT) + + if len(sys.argv) == 2 and sys.argv[1] == '-R': + config = 'R' + else: + config = 'D' + + app_path = create_app_copy(config) + + if sys.platform == 'darwin': + electron = os.path.join(app_path, 'Contents', 'MacOS', PRODUCT_NAME) + ffmpeg_name = 'libffmpeg.dylib' + ffmpeg_app_path = os.path.join(app_path, 'Contents', 'Frameworks', + '{0} Framework.framework'.format(PROJECT_NAME), + 'Libraries') + elif sys.platform == 'win32': + electron = os.path.join(app_path, '{0}.exe'.format(PROJECT_NAME)) + ffmpeg_app_path = app_path + ffmpeg_name = 'ffmpeg.dll' + else: + electron = os.path.join(app_path, PROJECT_NAME) + ffmpeg_app_path = app_path + ffmpeg_name = 'libffmpeg.so' + + # Copy ffmpeg without proprietary codecs into app + shutil.copy(os.path.join(FFMPEG_LIBCC_PATH, ffmpeg_name), ffmpeg_app_path) + + returncode = 0 + try: + test_path = os.path.join('spec', 'fixtures', 'no-proprietary-codecs.js') + subprocess.check_call([electron, test_path] + sys.argv[1:]) + except subprocess.CalledProcessError as e: + returncode = e.returncode + except KeyboardInterrupt: + returncode = 0 + + return returncode + + +# Create copy of app to install ffmpeg library without proprietary codecs into +def create_app_copy(config): + initial_app_path = os.path.join(SOURCE_ROOT, 'out', config) + app_path = os.path.join(SOURCE_ROOT, 'out', config + '-no-proprietary-codecs') + + if sys.platform == 'darwin': + app_name = '{0}.app'.format(PRODUCT_NAME) + initial_app_path = os.path.join(initial_app_path, app_name) + app_path = os.path.join(app_path, app_name) + + rm_rf(app_path) + shutil.copytree(initial_app_path, app_path, symlinks=True) + return app_path + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/spec/fixtures/no-proprietary-codecs.js b/spec/fixtures/no-proprietary-codecs.js new file mode 100644 index 000000000000..23a7d815a924 --- /dev/null +++ b/spec/fixtures/no-proprietary-codecs.js @@ -0,0 +1,47 @@ +// Verifies that Electron cannot play a video that uses proprietary codecs +// +// This application should be run with the ffmpeg that does not include +// proprietary codecs to ensure Electron uses it instead of the version +// that does include proprietary codecs. + +const {app, BrowserWindow, ipcMain} = require('electron') +const path = require('path') +const url = require('url') + +const MEDIA_ERR_SRC_NOT_SUPPORTED = 4 +const FIVE_MINUTES = 5 * 60 * 1000 + +let window + +app.once('ready', () => { + window = new BrowserWindow({ + show: false + }) + + window.loadURL(url.format({ + protocol: 'file', + slashed: true, + pathname: path.resolve(__dirname, 'asar', 'video.asar', 'index.html') + })) + + ipcMain.on('asar-video', (event, message, error) => { + if (message === 'ended') { + console.log('Video played, proprietary codecs are included') + app.exit(1) + return + } + + if (message === 'error' && error === MEDIA_ERR_SRC_NOT_SUPPORTED) { + app.exit(0) + return + } + + console.log(`Unexpected response from page: ${message} ${error}`) + app.exit(1) + }) + + setTimeout(() => { + console.log('No IPC message after 5 minutes') + app.exit(1) + }, FIVE_MINUTES) +})