• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
8var PlayerUtils = new function() {
9}
10
11// Prepares a video element for playback by setting default event handlers
12// and source attribute.
13PlayerUtils.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
39PlayerUtils.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
94PlayerUtils.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
134PlayerUtils.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
146PlayerUtils.initEMEPlayer = function(player) {
147  this.registerEMEEventListeners(player);
148  this.setVideoSource(player);
149};
150
151PlayerUtils.initPrefixedEMEPlayer = function(player) {
152  this.registerPrefixedEMEEventListeners(player);
153  this.setVideoSource(player);
154};
155
156// Return the appropriate player based on test configuration.
157PlayerUtils.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