Home | History | Annotate | Download | only in eme_player_js
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // The PlayerUtils provides utility functions to binding common media events
      6 // to specific player functions. It also provides functions to load media source
      7 // base on test configurations.
      8 var PlayerUtils = new function() {
      9 }
     10 
     11 // Prepares a video element for playback by setting default event handlers
     12 // and source attribute.
     13 PlayerUtils.registerDefaultEventListeners = function(player) {
     14   Utils.timeLog('Registering video event handlers.');
     15   // Map from event name to event listener function name.  It is common for
     16   // event listeners to be named onEventName.
     17   var eventListenerMap = {
     18     'needkey': 'onNeedKey',
     19     'webkitneedkey': 'onWebkitNeedKey',
     20     'webkitkeymessage': 'onWebkitKeyMessage',
     21     'webkitkeyadded': 'onWebkitKeyAdded',
     22     'webkitkeyerror': 'onWebkitKeyError'
     23   };
     24   for (eventName in eventListenerMap) {
     25     var eventListenerFunction = player[eventListenerMap[eventName]];
     26     if (eventListenerFunction) {
     27       player.video.addEventListener(eventName, function(e) {
     28         player[eventListenerMap[e.type]](e);
     29       });
     30     }
     31   }
     32   // List of events that fail tests.
     33   var failingEvents = ['error', 'abort'];
     34   for (var i = 0; i < failingEvents.length; i++) {
     35     player.video.addEventListener(failingEvents[i], Utils.failTest);
     36   }
     37 };
     38 
     39 PlayerUtils.registerEMEEventListeners = function(player) {
     40   player.video.addEventListener('needkey', function(message) {
     41 
     42     function addMediaKeySessionListeners(mediaKeySession) {
     43       mediaKeySession.addEventListener('message', function(message) {
     44         player.video.receivedKeyMessage = true;
     45         if (Utils.isHeartBeatMessage(message.message)) {
     46           Utils.timeLog('MediaKeySession onMessage - heart beat', message);
     47           player.video.receivedHeartbeat = true;
     48         }
     49         player.onMessage(message);
     50       });
     51       mediaKeySession.addEventListener('error', function(error) {
     52         Utils.failTest(error, KEY_ERROR);
     53       });
     54     }
     55 
     56     Utils.timeLog('Creating new media key session for contentType: ' +
     57                   message.contentType + ', initData: ' +
     58                   Utils.getHexString(message.initData));
     59     try {
     60       if (message.target.mediaKeys.createSession.length == 0) {
     61         // FIXME(jrummell): Remove this test (and else branch) once blink
     62         // uses the new API.
     63         var session = message.target.mediaKeys.createSession();
     64         addMediaKeySessionListeners(session);
     65         session.generateRequest(message.contentType, message.initData)
     66           .catch(function(error) {
     67             Utils.failTest(error, KEY_ERROR);
     68           });
     69       } else {
     70         var session = message.target.mediaKeys.createSession(
     71             message.contentType, message.initData);
     72         session.then(addMediaKeySessionListeners)
     73             .catch(function(error) {
     74               Utils.failTest(error, KEY_ERROR);
     75             });
     76       }
     77     } catch (e) {
     78       Utils.failTest(e);
     79     }
     80   });
     81   this.registerDefaultEventListeners(player);
     82   try {
     83     Utils.timeLog('Setting video media keys: ' + player.testConfig.keySystem);
     84     MediaKeys.create(player.testConfig.keySystem).then(function(mediaKeys) {
     85       player.video.setMediaKeys(mediaKeys);
     86     }).catch(function(error) {
     87       Utils.failTest(error, NOTSUPPORTEDERROR);
     88     });
     89   } catch (e) {
     90     Utils.failTest(e);
     91   }
     92 };
     93 
     94 PlayerUtils.registerPrefixedEMEEventListeners = function(player) {
     95  player.video.addEventListener('webkitneedkey', function(message) {
     96     var initData = message.initData;
     97     if (player.testConfig.sessionToLoad) {
     98       Utils.timeLog('Loading session: ' + player.testConfig.sessionToLoad);
     99       initData = Utils.convertToUint8Array(
    100           PREFIXED_API_LOAD_SESSION_HEADER + player.testConfig.sessionToLoad);
    101     }
    102     Utils.timeLog(player.testConfig.keySystem +
    103                   ' Generate key request, initData: ' +
    104                   Utils.getHexString(initData));
    105     try {
    106       message.target.webkitGenerateKeyRequest(player.testConfig.keySystem,
    107                                               initData);
    108     } catch (e) {
    109       Utils.failTest(e);
    110     }
    111   });
    112 
    113   player.video.addEventListener('webkitkeyadded', function(message) {
    114     Utils.timeLog('onWebkitKeyAdded', message);
    115     message.target.receivedKeyAdded = true;
    116   });
    117 
    118   player.video.addEventListener('webkitkeyerror', function(error) {
    119     Utils.timeLog('onWebkitKeyError', error);
    120     Utils.failTest(error, KEY_ERROR);
    121   });
    122 
    123   player.video.addEventListener('webkitkeymessage', function(message) {
    124     Utils.timeLog('onWebkitKeyMessage', message);
    125     message.target.receivedKeyMessage = true;
    126     if (Utils.isHeartBeatMessage(message.message)) {
    127       Utils.timeLog('onWebkitKeyMessage - heart beat', message);
    128       message.target.receivedHeartbeat = true;
    129     }
    130   });
    131   this.registerDefaultEventListeners(player);
    132 };
    133 
    134 PlayerUtils.setVideoSource = function(player) {
    135   if (player.testConfig.useMSE) {
    136     Utils.timeLog('Loading media using MSE.');
    137     var mediaSource =
    138         MediaSourceUtils.loadMediaSourceFromTestConfig(player.testConfig);
    139     player.video.src = window.URL.createObjectURL(mediaSource);
    140   } else {
    141     Utils.timeLog('Loading media using src.');
    142     player.video.src = player.testConfig.mediaFile;
    143   }
    144 };
    145 
    146 PlayerUtils.initEMEPlayer = function(player) {
    147   this.registerEMEEventListeners(player);
    148   this.setVideoSource(player);
    149 };
    150 
    151 PlayerUtils.initPrefixedEMEPlayer = function(player) {
    152   this.registerPrefixedEMEEventListeners(player);
    153   this.setVideoSource(player);
    154 };
    155 
    156 // Return the appropriate player based on test configuration.
    157 PlayerUtils.createPlayer = function(video, testConfig) {
    158   // Update keySystem if using prefixed Clear Key since it is not available as a
    159   // separate key system to choose from; however it can be set in URL query.
    160   var usePrefixedEME = testConfig.usePrefixedEME;
    161   if (testConfig.keySystem == CLEARKEY && usePrefixedEME)
    162     testConfig.keySystem = PREFIXED_CLEARKEY;
    163 
    164   function getPlayerType(keySystem) {
    165     switch (keySystem) {
    166       case WIDEVINE_KEYSYSTEM:
    167         if (usePrefixedEME)
    168           return PrefixedWidevinePlayer;
    169         return WidevinePlayer;
    170       case PREFIXED_CLEARKEY:
    171         return PrefixedClearKeyPlayer;
    172       case EXTERNAL_CLEARKEY:
    173       case CLEARKEY:
    174         if (usePrefixedEME)
    175           return PrefixedClearKeyPlayer;
    176         return ClearKeyPlayer;
    177       case FILE_IO_TEST_KEYSYSTEM:
    178         if (usePrefixedEME)
    179           return FileIOTestPlayer;
    180       default:
    181         Utils.timeLog(keySystem + ' is not a known key system');
    182         if (usePrefixedEME)
    183           return PrefixedClearKeyPlayer;
    184         return ClearKeyPlayer;
    185     }
    186   }
    187   var Player = getPlayerType(testConfig.keySystem);
    188   return new Player(video, testConfig);
    189 };
    190