BLD-915: Fix issues with different videoIDs.

This commit is contained in:
polesye
2014-03-11 17:38:29 +02:00
parent e117957e2a
commit ddf41ce9c5
13 changed files with 256 additions and 122 deletions

View File

@@ -15,8 +15,8 @@ SERVICES = {
}
@before.all
def start_stubs():
@before.each_scenario
def start_stubs(_):
"""
Start each stub service running on a local port.
"""
@@ -25,7 +25,7 @@ def start_stubs():
setattr(world, name, fake_server)
@after.all
@after.each_scenario
def stop_stubs(_):
"""
Shut down each stub service.

View File

@@ -5,7 +5,6 @@ Stub implementation of YouTube for acceptance tests.
from .http import StubHttpRequestHandler, StubHttpService
import json
import time
import requests
from urlparse import urlparse
from collections import OrderedDict
@@ -80,7 +79,7 @@ class StubYouTubeHandler(StubHttpRequestHandler):
'data': OrderedDict({
'id': youtube_id,
'message': message,
'duration': 60,
'duration': 60 if youtube_id == 'OEoXaMPEzfM' else 77,
})
})
response = "{cb}({data})".format(cb=callback, data=json.dumps(data))

View File

@@ -233,25 +233,42 @@ function (Initialize) {
'1.0': 'testId',
'1.50': 'videoId'
},
youtubeId: Initialize.prototype.youtubeId
youtubeId: Initialize.prototype.youtubeId,
isFlashMode: jasmine.createSpy().andReturn(false)
};
});
it('returns duration for current video', function () {
var expected = Initialize.prototype.getDuration.call(state);
expect(expected).toEqual(100);
});
var msg = 'returns duration for the 1.0 speed as a fallback';
var msg = 'returns duration for the 1.0 speed if speed is not 1.0';
it(msg, function () {
var expected;
state.speed = '2.0';
state.speed = '1.50';
expected = Initialize.prototype.getDuration.call(state);
expect(expected).toEqual(400);
});
describe('Flash mode', function () {
it('returns duration for current video', function () {
var expected;
state.isFlashMode.andReturn(true);
expected = Initialize.prototype.getDuration.call(state);
expect(expected).toEqual(100);
});
var msg = 'returns duration for the 1.0 speed as a fall-back';
it(msg, function () {
var expected;
state.isFlashMode.andReturn(true);
state.speed = '2.0';
expected = Initialize.prototype.getDuration.call(state);
expect(expected).toEqual(400);
});
});
});
describe('youtubeId', function () {
@@ -262,7 +279,8 @@ function (Initialize) {
'0.50': '7tqY6eQzVhE',
'1.0': 'cogebirgzzM',
'1.50': 'abcdefghijkl'
}
},
isFlashMode: jasmine.createSpy().andReturn(false)
};
});
@@ -278,14 +296,25 @@ function (Initialize) {
});
});
describe('without speed', function () {
describe('without speed for flash mode', function () {
it('return the video id for current speed', function () {
var expected = Initialize.prototype.youtubeId.call(state);
var expected;
state.isFlashMode.andReturn(true);
expected = Initialize.prototype.youtubeId.call(state);
expect(expected).toEqual('abcdefghijkl');
});
});
describe('without speed for youtube html5 mode', function () {
it('return the video id for 1.0x speed', function () {
var expected = Initialize.prototype.youtubeId.call(state);
expect(expected).toEqual('cogebirgzzM');
});
});
describe('speed is absent in the list of video speeds', function () {
it('return the video id for 1.0x speed', function () {
var expected = Initialize.prototype.youtubeId.call(state, '0.0');

View File

@@ -55,11 +55,7 @@
});
waitsFor(function () {
if (state.videoCaption.loaded === true) {
return true;
}
return false;
return state.videoCaption.loaded;
}, 'Expect captions to be loaded.', WAIT_TIMEOUT);
runs(function () {
@@ -77,17 +73,15 @@
});
});
it('fetch the caption in Youtube mode', function () {
it('fetch the caption in Flash mode', function () {
runs(function () {
state = jasmine.initializePlayerYouTube();
spyOn(state, 'isFlashMode').andReturn(true);
state.videoCaption.fetchCaption();
});
waitsFor(function () {
if (state.videoCaption.loaded === true) {
return true;
}
return false;
return state.videoCaption.loaded;
}, 'Expect captions to be loaded.', WAIT_TIMEOUT);
runs(function () {
@@ -106,6 +100,31 @@
});
});
it('fetch the caption in Youtube mode', function () {
runs(function () {
state = jasmine.initializePlayerYouTube();
});
waitsFor(function () {
return state.videoCaption.loaded;
}, 'Expect captions to be loaded.', WAIT_TIMEOUT);
runs(function () {
expect($.ajaxWithPrefix).toHaveBeenCalledWith({
url: '/transcript/translation',
notifyOnError: false,
data: jasmine.any(Object),
success: jasmine.any(Function),
error: jasmine.any(Function)
});
expect($.ajaxWithPrefix.mostRecentCall.args[0].data)
.toEqual({
language: 'en',
videoId: 'cogebirgzzM'
});
});
});
it('bind the hide caption button', function () {
state = jasmine.initializePlayer();
expect($('.hide-subtitles')).toHandleWith(

View File

@@ -105,6 +105,7 @@ function (VideoPlayer) {
it('create Flash player', function () {
var player;
spyOn($.fn, 'trigger');
state = jasmine.initializePlayerYouTube();
state.videoEl = state.el.find('video, iframe').width(100);
player = state.videoPlayer.player;
@@ -715,7 +716,8 @@ function (VideoPlayer) {
},
currentPlayerMode: 'html5',
trigger: function () {},
browserIsFirefox: false
browserIsFirefox: false,
isFlashMode: jasmine.createSpy().andReturn(false)
};
});
@@ -1015,7 +1017,8 @@ function (VideoPlayer) {
updatePlayTime: jasmine.createSpy(),
setPlaybackRate: jasmine.createSpy(),
player: jasmine.createSpyObj('player', ['setPlaybackRate'])
}
},
isFlashMode: jasmine.createSpy().andReturn(false)
};
});
@@ -1033,7 +1036,7 @@ function (VideoPlayer) {
});
it('convert the current time to the new speed', function () {
state.currentPlayerMode = 'flash';
state.isFlashMode.andReturn(true);
VideoPlayer.prototype.onSpeedChange.call(state, '0.75', false);
expect(state.videoPlayer.currentTime).toBe('120.000');
});

View File

@@ -65,6 +65,7 @@ function (VideoPlayer, VideoStorage) {
getDuration: getDuration,
getVideoMetadata: getVideoMetadata,
initialize: initialize,
isFlashMode: isFlashMode,
parseSpeed: parseSpeed,
parseVideoSources: parseVideoSources,
parseYoutubeStreams: parseYoutubeStreams,
@@ -550,7 +551,7 @@ function (VideoPlayer, VideoStorage) {
_this.videos[speed] = video[1];
});
return true;
return _.isString(this.videos['1.0']);
}
// function parseVideoSources(, mp4Source, webmSource, oggSource)
@@ -702,7 +703,11 @@ function (VideoPlayer, VideoStorage) {
}
function youtubeId(speed) {
return this.videos[speed || this.speed] || this.videos['1.0'];
var currentSpeed = this.isFlashMode() ? this.speed : '1.0';
return this.videos[speed] ||
this.videos[currentSpeed] ||
this.videos['1.0'];
}
function getDuration() {
@@ -713,6 +718,10 @@ function (VideoPlayer, VideoStorage) {
}
}
function isFlashMode() {
return this.currentPlayerMode === 'flash';
}
function getCurrentLanguage() {
var keys = _.keys(this.config.transcriptLanguages);

View File

@@ -73,7 +73,7 @@ function (HTML5Video, Resizer) {
state.videoPlayer.ready = _.once(function () {
$(window).on('unload', state.saveState);
if (state.currentPlayerMode !== 'flash') {
if (!state.isFlashMode()) {
state.videoPlayer.setPlaybackRate(state.speed);
}
state.videoPlayer.player.setVolume(state.currentVolume);
@@ -100,7 +100,7 @@ function (HTML5Video, Resizer) {
modestbranding: 1
};
if (state.currentPlayerMode !== 'flash') {
if (!state.isFlashMode()) {
state.videoPlayer.playerVars.html5 = 1;
}
@@ -140,11 +140,8 @@ function (HTML5Video, Resizer) {
}, false);
} else { // if (state.videoType === 'youtube') {
if (state.currentPlayerMode === 'flash') {
youTubeId = state.youtubeId();
} else {
youTubeId = state.youtubeId('1.0');
}
youTubeId = state.youtubeId();
state.videoPlayer.player = new YT.Player(state.id, {
playerVars: state.videoPlayer.playerVars,
videoId: youTubeId,
@@ -162,22 +159,7 @@ function (HTML5Video, Resizer) {
videoHeight = player.attr('height') || player.height();
_resize(state, videoWidth, videoHeight);
// After initialization, update the VCR with total time.
// At this point only the metadata duration is available (not
// very precise), but it is better than having 00:00:00 for
// total time.
if (state.youtubeMetadataReceived) {
// Metadata was already received, and is available.
_updateVcrAndRegion(state);
} else {
// We wait for metadata to arrive, before we request the update
// of the VCR video time, and of the start-end time region.
// Metadata contains duration of the video.
state.el.on('metadata_received', function () {
_updateVcrAndRegion(state);
});
}
_updateVcrAndRegion(state, true);
});
}
@@ -185,36 +167,53 @@ function (HTML5Video, Resizer) {
dfd.resolve();
}
}
function _updateVcrAndRegion(state, isYoutube) {
var update = function (state) {
var duration = state.videoPlayer.duration(),
time;
function _updateVcrAndRegion(state) {
var duration = state.videoPlayer.duration(),
time;
time = state.videoPlayer.figureOutStartingTime(duration);
time = state.videoPlayer.figureOutStartingTime(duration);
// Update the VCR.
state.trigger(
'videoControl.updateVcrVidTime',
{
time: time,
duration: duration
}
);
// Update the VCR.
state.trigger(
'videoControl.updateVcrVidTime',
{
time: time,
duration: duration
}
);
// Update the time slider.
state.trigger(
'videoProgressSlider.updateStartEndTimeRegion',
{
duration: duration
}
);
state.trigger(
'videoProgressSlider.updatePlayTime',
{
time: time,
duration: duration
}
);
};
// Update the time slider.
state.trigger(
'videoProgressSlider.updateStartEndTimeRegion',
{
duration: duration
}
);
state.trigger(
'videoProgressSlider.updatePlayTime',
{
time: time,
duration: duration
}
);
// After initialization, update the VCR with total time.
// At this point only the metadata duration is available (not
// very precise), but it is better than having 00:00:00 for
// total time.
if (state.youtubeMetadataReceived || !isYoutube) {
// Metadata was already received, and is available.
update(state);
} else {
// We wait for metadata to arrive, before we request the update
// of the VCR video time, and of the start-end time region.
// Metadata contains duration of the video.
state.el.on('metadata_received', function () {
update(state);
});
}
}
function _resize(state, videoWidth, videoHeight) {
@@ -271,6 +270,8 @@ function (HTML5Video, Resizer) {
}
});
_updateVcrAndRegion(state, true);
state.trigger('videoCaption.fetchCaption', null);
state.resizer.setElement(state.el.find('iframe')).align();
}
@@ -348,7 +349,7 @@ function (HTML5Video, Resizer) {
// where in Firefox speed switching to 1.0 in HTML5 player mode is
// handled incorrectly by YouTube API.
methodName = 'cueVideoById';
youtubeId = this.youtubeId();
youtubeId = this.youtubeId(newSpeed);
if (this.videoPlayer.isPlaying()) {
methodName = 'loadVideoById';
@@ -360,10 +361,9 @@ function (HTML5Video, Resizer) {
}
function onSpeedChange(newSpeed) {
var time = this.videoPlayer.currentTime,
isFlash = this.currentPlayerMode === 'flash';
var time = this.videoPlayer.currentTime;
if (isFlash) {
if (this.isFlashMode()) {
this.videoPlayer.currentTime = Time.convert(
time,
parseFloat(this.speed),
@@ -605,6 +605,11 @@ function (HTML5Video, Resizer) {
}
}
if (this.isFlashMode()) {
this.setSpeed(this.speed);
this.trigger('videoSpeedControl.setSpeed', this.speed);
}
if (this.currentPlayerMode === 'html5') {
this.videoPlayer.player.setPlaybackRate(this.speed);
}
@@ -653,7 +658,7 @@ function (HTML5Video, Resizer) {
videoPlayer.startTime = this.config.startTime;
if (videoPlayer.startTime >= duration) {
videoPlayer.startTime = 0;
} else if (this.currentPlayerMode === 'flash') {
} else if (this.isFlashMode()) {
videoPlayer.startTime /= Number(this.speed);
}
@@ -664,7 +669,7 @@ function (HTML5Video, Resizer) {
) {
videoPlayer.stopAtEndTime = false;
videoPlayer.endTime = null;
} else if (this.currentPlayerMode === 'flash') {
} else if (this.isFlashMode()) {
videoPlayer.endTime /= Number(this.speed);
}
}
@@ -749,11 +754,7 @@ function (HTML5Video, Resizer) {
// HTML5 video sources play fine from start-time in both Chrome
// and Firefox.
if (this.browserIsFirefox && this.videoType === 'youtube') {
if (this.currentPlayerMode === 'flash') {
youTubeId = this.youtubeId();
} else {
youTubeId = this.youtubeId('1.0');
}
youTubeId = this.youtubeId();
// When we will call cueVideoById() for some strange reason
// an ENDED event will be fired. It really does no damage

View File

@@ -104,8 +104,7 @@ function () {
// whole slider). Remember that endTime === null means the end-time
// is set to the end of video by default.
function updateStartEndTimeRegion(params) {
var isFlashMode = this.currentPlayerMode === 'flash',
left, width, start, end, duration, rangeParams;
var left, width, start, end, duration, rangeParams;
// We must have a duration in order to determine the area of range.
// It also must be non-zero.
@@ -120,7 +119,7 @@ function () {
if (start > duration) {
start = 0;
} else if (isFlashMode) {
} else if (this.isFlashMode()) {
start /= Number(this.speed);
}
@@ -128,7 +127,7 @@ function () {
// video, then we set it to the end of the video.
if (end === null || end > duration) {
end = duration;
} else if (isFlashMode) {
} else if (this.isFlashMode()) {
end /= Number(this.speed);
}

View File

@@ -155,7 +155,7 @@ function () {
}
this.el.on('speedchange', function () {
if (self.currentPlayerMode === 'flash') {
if (self.isFlashMode()) {
Caption.fetchCaption();
}
});
@@ -628,7 +628,7 @@ function () {
if (this.videoCaption.loaded) {
// Current mode === 'flash' can only be for YouTube videos. So, we
// don't have to also check for videoType === 'youtube'.
if (this.currentPlayerMode === 'flash') {
if (this.isFlashMode()) {
// Total play time changes with speed change. Also there is
// a 250 ms delay we have to take into account.
time = Math.round(
@@ -670,7 +670,7 @@ function () {
// Current mode === 'flash' can only be for YouTube videos. So, we
// don't have to also check for videoType === 'youtube'.
if (this.currentPlayerMode === 'flash') {
if (this.isFlashMode()) {
// Total play time changes with speed change. Also there is
// a 250 ms delay we have to take into account.
time = Math.round(

View File

@@ -0,0 +1,11 @@
{
"start": [
1000
],
"end": [
2000
],
"text": [
"Equal transcripts"
]
}