mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
update event binding
This commit is contained in:
parent
bcfbb01b4b
commit
a08715f2f2
10 changed files with 164 additions and 126 deletions
|
@ -16,12 +16,12 @@
|
|||
},
|
||||
"devDependencies": {},
|
||||
"ignore": [],
|
||||
"version": "1.0.13",
|
||||
"_release": "1.0.13",
|
||||
"version": "1.0.15",
|
||||
"_release": "1.0.15",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.0.13",
|
||||
"commit": "50abac508289fd4db77f6d52ba1ee351b57baec2"
|
||||
"tag": "1.0.15",
|
||||
"commit": "2b89c4815135e6acef56ec14d56ad0a1d7551e00"
|
||||
},
|
||||
"_source": "git://github.com/MediaBrowser/Emby.ApiClient.Javascript.git",
|
||||
"_target": "~1.0.3",
|
||||
|
|
|
@ -2,22 +2,20 @@
|
|||
|
||||
function getCallbacks(obj, name) {
|
||||
|
||||
ensureCallbacks(obj, name);
|
||||
|
||||
return obj._callbacks[name];
|
||||
}
|
||||
|
||||
function ensureCallbacks(obj, name) {
|
||||
|
||||
if (!obj) {
|
||||
throw new Error("obj cannot be null!");
|
||||
}
|
||||
|
||||
obj._callbacks = obj._callbacks || {};
|
||||
|
||||
if (!obj._callbacks[name]) {
|
||||
var list = obj._callbacks[name];
|
||||
|
||||
if (!list) {
|
||||
obj._callbacks[name] = [];
|
||||
list = obj._callbacks[name];
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -26,17 +24,17 @@
|
|||
|
||||
var list = getCallbacks(obj, eventName);
|
||||
|
||||
if (list.indexOf(fn) == -1) {
|
||||
list.push(fn);
|
||||
}
|
||||
list.push(fn);
|
||||
},
|
||||
|
||||
off: function (obj, eventName, fn) {
|
||||
|
||||
var list = getCallbacks(obj, eventName);
|
||||
obj._callbacks[name] = list.filter(function (i) {
|
||||
return i != fn;
|
||||
});
|
||||
|
||||
var i = list.indexOf(fn);
|
||||
if (i != -1) {
|
||||
list.splice(i, 1);
|
||||
}
|
||||
},
|
||||
|
||||
trigger: function (obj, eventName) {
|
||||
|
@ -53,7 +51,9 @@
|
|||
eventArgs.push(additionalArgs[i]);
|
||||
}
|
||||
|
||||
getCallbacks(obj, eventName).forEach(function (c) {
|
||||
var callbacks = getCallbacks(obj, eventName).slice(0);
|
||||
|
||||
callbacks.forEach(function (c) {
|
||||
c.apply(obj, eventArgs);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -24,14 +24,14 @@
|
|||
"web-component-tester": "*"
|
||||
},
|
||||
"private": true,
|
||||
"homepage": "https://github.com/Polymer/polymer",
|
||||
"homepage": "https://github.com/polymer/polymer",
|
||||
"_release": "1.2.3",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.2.3",
|
||||
"commit": "aa535d1675342007cbf64dc9c66497cf74cbc616"
|
||||
},
|
||||
"_source": "git://github.com/Polymer/polymer.git",
|
||||
"_source": "git://github.com/polymer/polymer.git",
|
||||
"_target": "^1.0.0",
|
||||
"_originalSource": "Polymer/polymer"
|
||||
"_originalSource": "polymer/polymer"
|
||||
}
|
|
@ -162,7 +162,7 @@
|
|||
if (options.showConfirmation !== false) {
|
||||
Dashboard.processServerConfigurationUpdateResult();
|
||||
}
|
||||
$(self).trigger('submitted');
|
||||
Events.trigger(self, 'submitted');
|
||||
|
||||
}, function () {
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
|
|
@ -483,7 +483,7 @@
|
|||
}
|
||||
};
|
||||
|
||||
$(castPlayer).on("connect", function (e) {
|
||||
Events.on(castPlayer, "connect", function (e) {
|
||||
|
||||
MediaController.setActivePlayer(PlayerName, self.getCurrentTargetInfo());
|
||||
|
||||
|
@ -492,7 +492,7 @@
|
|||
self.lastPlayerData = {};
|
||||
});
|
||||
|
||||
$(castPlayer).on("playbackstart", function (e, data) {
|
||||
Events.on(castPlayer, "playbackstart", function (e, data) {
|
||||
|
||||
Logger.log('cc: playbackstart');
|
||||
|
||||
|
@ -502,7 +502,7 @@
|
|||
Events.trigger(self, "playbackstart", [state]);
|
||||
});
|
||||
|
||||
$(castPlayer).on("playbackstop", function (e, data) {
|
||||
Events.on(castPlayer, "playbackstop", function (e, data) {
|
||||
|
||||
Logger.log('cc: playbackstop');
|
||||
var state = self.getPlayerStateInternal(data);
|
||||
|
@ -513,7 +513,7 @@
|
|||
self.lastPlayerData = {};
|
||||
});
|
||||
|
||||
$(castPlayer).on("playbackprogress", function (e, data) {
|
||||
Events.on(castPlayer, "playbackprogress", function (e, data) {
|
||||
|
||||
Logger.log('cc: positionchange');
|
||||
var state = self.getPlayerStateInternal(data);
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
function onEnded() {
|
||||
showStatusBar();
|
||||
$(self).trigger('ended');
|
||||
Events.trigger(self, 'ended');
|
||||
}
|
||||
|
||||
function onTimeUpdate() {
|
||||
|
@ -46,50 +46,58 @@
|
|||
// }
|
||||
//}
|
||||
|
||||
$(self).trigger('timeupdate');
|
||||
Events.trigger(self, 'timeupdate');
|
||||
}
|
||||
|
||||
function onVolumeChange() {
|
||||
$(self).trigger('volumechange');
|
||||
Events.trigger(self, 'volumechange');
|
||||
}
|
||||
|
||||
function onOneAudioPlaying() {
|
||||
function onOneAudioPlaying(e) {
|
||||
|
||||
var elem = e.target;
|
||||
elem.removeEventListener('playing', onOneAudioPlaying);
|
||||
$('.mediaPlayerAudioContainer').hide();
|
||||
}
|
||||
|
||||
function onPlaying() {
|
||||
$(self).trigger('playing');
|
||||
Events.trigger(self, 'playing');
|
||||
}
|
||||
|
||||
function onPlay() {
|
||||
$(self).trigger('play');
|
||||
Events.trigger(self, 'play');
|
||||
}
|
||||
|
||||
function onPause() {
|
||||
$(self).trigger('pause');
|
||||
Events.trigger(self, 'pause');
|
||||
}
|
||||
|
||||
function onClick() {
|
||||
$(self).trigger('click');
|
||||
Events.trigger(self, 'click');
|
||||
}
|
||||
|
||||
function onDblClick() {
|
||||
$(self).trigger('dblclick');
|
||||
Events.trigger(self, 'dblclick');
|
||||
}
|
||||
|
||||
function onError() {
|
||||
function onError(e) {
|
||||
|
||||
var errorCode = this.error ? this.error.code : '';
|
||||
var elem = e.target;
|
||||
var errorCode = elem.error ? elem.error.code : '';
|
||||
Logger.log('Media element error code: ' + errorCode);
|
||||
|
||||
showStatusBar();
|
||||
$(self).trigger('error');
|
||||
Events.trigger(self, 'error');
|
||||
}
|
||||
|
||||
function onLoadedMetadata() {
|
||||
function onLoadedMetadata(e) {
|
||||
|
||||
var elem = e.target;
|
||||
|
||||
elem.removeEventListener('loadedmetadata', onLoadedMetadata);
|
||||
|
||||
if (!hlsPlayer) {
|
||||
this.play();
|
||||
elem.play();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,14 +127,17 @@
|
|||
return 0;
|
||||
}
|
||||
|
||||
function onOneVideoPlaying() {
|
||||
function onOneVideoPlaying(e) {
|
||||
|
||||
hideStatusBar();
|
||||
|
||||
var element = e.target;
|
||||
element.removeEventListener('playing', onOneVideoPlaying);
|
||||
|
||||
var requiresNativeControls = !self.enableCustomVideoControls();
|
||||
|
||||
if (requiresNativeControls) {
|
||||
$(this).attr('controls', 'controls');
|
||||
$(element).attr('controls', 'controls');
|
||||
}
|
||||
|
||||
if (requiresSettingStartTimeOnStart) {
|
||||
|
@ -138,7 +149,6 @@
|
|||
if (startPositionInSeekParam && src.indexOf('.m3u8') != -1) {
|
||||
|
||||
var delay = browserInfo.safari ? 2500 : 0;
|
||||
var element = this;
|
||||
if (delay) {
|
||||
setTimeout(function () {
|
||||
element.currentTime = startPositionInSeekParam;
|
||||
|
@ -173,15 +183,18 @@
|
|||
elem = $('.mediaPlayerAudio');
|
||||
}
|
||||
|
||||
return $(elem)
|
||||
.on('timeupdate', onTimeUpdate)
|
||||
.on('ended', onEnded)
|
||||
.on('volumechange', onVolumeChange)
|
||||
.one('playing', onOneAudioPlaying)
|
||||
.on('play', onPlay)
|
||||
.on('pause', onPause)
|
||||
.on('playing', onPlaying)
|
||||
.on('error', onError)[0];
|
||||
elem = elem[0];
|
||||
|
||||
elem.addEventListener('playing', onOneAudioPlaying);
|
||||
elem.addEventListener('timeupdate', onTimeUpdate);
|
||||
elem.addEventListener('ended', onEnded);
|
||||
elem.addEventListener('volumechange', onVolumeChange);
|
||||
elem.addEventListener('error', onError);
|
||||
elem.addEventListener('pause', onPause);
|
||||
elem.addEventListener('play', onPlay);
|
||||
elem.addEventListener('playing', onPlaying);
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
function enableHlsPlayer(src) {
|
||||
|
@ -221,18 +234,24 @@
|
|||
|
||||
var elem = $('#videoElement', '#videoPlayer').prepend(html);
|
||||
|
||||
return $('.itemVideo', elem)
|
||||
.one('.loadedmetadata', onLoadedMetadata)
|
||||
.one('playing', onOneVideoPlaying)
|
||||
.on('timeupdate', onTimeUpdate)
|
||||
.on('ended', onEnded)
|
||||
.on('volumechange', onVolumeChange)
|
||||
.on('play', onPlay)
|
||||
.on('pause', onPause)
|
||||
.on('playing', onPlaying)
|
||||
.on('click', onClick)
|
||||
.on('dblclick', onDblClick)
|
||||
.on('error', onError)[0];
|
||||
var itemVideo = $('.itemVideo', elem)[0];
|
||||
|
||||
itemVideo.addEventListener('loadedmetadata', onLoadedMetadata);
|
||||
itemVideo.addEventListener('playing', onOneVideoPlaying);
|
||||
|
||||
itemVideo.addEventListener('timeupdate', onTimeUpdate);
|
||||
itemVideo.addEventListener('ended', onEnded);
|
||||
itemVideo.addEventListener('volumechange', onVolumeChange);
|
||||
|
||||
itemVideo.addEventListener('voluplaymechange', onPlay);
|
||||
itemVideo.addEventListener('pause', onPause);
|
||||
itemVideo.addEventListener('playing', onPlaying);
|
||||
|
||||
itemVideo.addEventListener('click', onClick);
|
||||
itemVideo.addEventListener('dblclick', onDblClick);
|
||||
itemVideo.addEventListener('error', onError);
|
||||
|
||||
return itemVideo;
|
||||
}
|
||||
|
||||
// Save this for when playback stops, because querying the time at that point might return 0
|
||||
|
@ -384,7 +403,7 @@
|
|||
|
||||
setTracks(elem, tracks);
|
||||
|
||||
$(elem).one("loadedmetadata", onLoadedMetadata);
|
||||
elem.addEventListener("loadedmetadata", onLoadedMetadata);
|
||||
playNow = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -543,6 +543,10 @@
|
|||
|
||||
self.playNextAfterEnded = function () {
|
||||
|
||||
console.log('playNextAfterEnded');
|
||||
|
||||
Events.off(this, 'ended', self.playNextAfterEnded);
|
||||
|
||||
self.nextTrack();
|
||||
};
|
||||
|
||||
|
@ -661,16 +665,18 @@
|
|||
Events.off(mediaRenderer, 'ended', self.onPlaybackStopped);
|
||||
Events.off(mediaRenderer, 'ended', self.playNextAfterEnded);
|
||||
|
||||
$(mediaRenderer).one("play", function () {
|
||||
function onPlayingOnce() {
|
||||
|
||||
Events.off(this, "play", onPlayingOnce);
|
||||
Events.on(this, 'ended', self.onPlaybackStopped);
|
||||
|
||||
$(this).one('ended', self.playNextAfterEnded);
|
||||
Events.on(this, 'ended', self.playNextAfterEnded);
|
||||
|
||||
self.startProgressInterval();
|
||||
sendProgressUpdate();
|
||||
}
|
||||
|
||||
});
|
||||
Events.on(mediaRenderer, "play", onPlayingOnce);
|
||||
|
||||
if (self.currentItem.MediaType == "Video") {
|
||||
ApiClient.stopActiveEncodings(playSessionId).then(function () {
|
||||
|
@ -1550,25 +1556,23 @@
|
|||
|
||||
if (mediaRenderer) {
|
||||
|
||||
mediaRenderer.stop();
|
||||
|
||||
Events.off(mediaRenderer, 'ended', self.playNextAfterEnded);
|
||||
|
||||
$(mediaRenderer).one("ended", function () {
|
||||
|
||||
$(this).off('.mediaplayerevent');
|
||||
|
||||
this.cleanup(destroyRenderer);
|
||||
|
||||
self.currentMediaRenderer = null;
|
||||
self.currentItem = null;
|
||||
self.currentMediaSource = null;
|
||||
self.currentSubtitleStreamIndex = null;
|
||||
self.streamInfo = {};
|
||||
|
||||
});
|
||||
mediaRenderer.stop();
|
||||
|
||||
Events.trigger(mediaRenderer, "ended");
|
||||
//self.onPlaybackStopped.call(mediaRenderer);
|
||||
|
||||
// TODO: Unbind video events
|
||||
unBindAudioEvents(mediaRenderer);
|
||||
|
||||
mediaRenderer.cleanup(destroyRenderer);
|
||||
|
||||
self.currentMediaRenderer = null;
|
||||
self.currentItem = null;
|
||||
self.currentMediaSource = null;
|
||||
self.currentSubtitleStreamIndex = null;
|
||||
self.streamInfo = {};
|
||||
|
||||
} else {
|
||||
self.currentMediaRenderer = null;
|
||||
|
@ -1583,6 +1587,14 @@
|
|||
}
|
||||
};
|
||||
|
||||
function unBindAudioEvents(mediaRenderer) {
|
||||
|
||||
Events.off(mediaRenderer, "volumechange", onVolumeChange);
|
||||
Events.off(mediaRenderer, "pause", onPause);
|
||||
Events.off(mediaRenderer, "playing", onPlaying);
|
||||
Events.off(mediaRenderer, "timeupdate", onTimeUpdate);
|
||||
}
|
||||
|
||||
self.isPlaying = function () {
|
||||
return self.playlist.length > 0;
|
||||
};
|
||||
|
@ -1767,8 +1779,8 @@
|
|||
|
||||
var mediaRenderer = this;
|
||||
|
||||
Events.off(mediaRenderer, '.mediaplayerevent');
|
||||
|
||||
// TODO: Unbind other events
|
||||
unBindAudioEvents(mediaRenderer);
|
||||
Events.off(mediaRenderer, 'ended', self.onPlaybackStopped);
|
||||
|
||||
var item = self.currentItem;
|
||||
|
@ -1790,6 +1802,8 @@
|
|||
|
||||
self.onPlaystateChange = function (mediaRenderer) {
|
||||
|
||||
console.log('mediaplayer onPlaystateChange');
|
||||
|
||||
var state = self.getPlayerStateInternal(mediaRenderer, self.currentItem, self.currentMediaSource);
|
||||
|
||||
Events.trigger(self, 'playstatechange', [state]);
|
||||
|
@ -1939,44 +1953,24 @@
|
|||
poster: self.getPosterUrl(item)
|
||||
});
|
||||
|
||||
Events.on(mediaRenderer, "volumechange.mediaplayerevent", function () {
|
||||
function onPlayingOnce() {
|
||||
|
||||
Logger.log('audio element event: volumechange');
|
||||
|
||||
self.onVolumeChanged(this);
|
||||
|
||||
});
|
||||
|
||||
$(mediaRenderer).one("playing.mediaplayerevent", function () {
|
||||
Events.off(mediaRenderer, "playing", onPlayingOnce);
|
||||
|
||||
Logger.log('audio element event: playing');
|
||||
|
||||
// For some reason this is firing at the start, so don't bind until playback has begun
|
||||
Events.on(this, 'ended', self.onPlaybackStopped);
|
||||
Events.on(mediaRenderer, 'ended', self.onPlaybackStopped);
|
||||
Events.on(mediaRenderer, 'ended', self.playNextAfterEnded);
|
||||
|
||||
$(this).one('ended', self.playNextAfterEnded);
|
||||
self.onPlaybackStart(mediaRenderer, item, mediaSource);
|
||||
}
|
||||
|
||||
self.onPlaybackStart(this, item, mediaSource);
|
||||
|
||||
}).on("pause.mediaplayerevent", function () {
|
||||
|
||||
Logger.log('audio element event: pause');
|
||||
|
||||
self.onPlaystateChange(this);
|
||||
|
||||
// In the event timeupdate isn't firing, at least we can update when this happens
|
||||
self.setCurrentTime(self.getCurrentTicks());
|
||||
|
||||
}).on("playing.mediaplayerevent", function () {
|
||||
|
||||
Logger.log('audio element event: playing');
|
||||
|
||||
self.onPlaystateChange(this);
|
||||
|
||||
// In the event timeupdate isn't firing, at least we can update when this happens
|
||||
self.setCurrentTime(self.getCurrentTicks());
|
||||
|
||||
}).on("timeupdate.mediaplayerevent", onTimeUpdate);
|
||||
Events.on(mediaRenderer, "volumechange", onVolumeChange);
|
||||
Events.on(mediaRenderer, "playing", onPlayingOnce);
|
||||
Events.on(mediaRenderer, "pause", onPause);
|
||||
Events.on(mediaRenderer, "playing", onPlaying);
|
||||
Events.on(mediaRenderer, "timeupdate", onTimeUpdate);
|
||||
|
||||
self.currentMediaRenderer = mediaRenderer;
|
||||
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
|
||||
|
@ -1994,6 +1988,34 @@
|
|||
});
|
||||
}
|
||||
|
||||
function onVolumeChange() {
|
||||
Logger.log('audio element event: pause');
|
||||
|
||||
self.onPlaystateChange(this);
|
||||
|
||||
// In the event timeupdate isn't firing, at least we can update when this happens
|
||||
self.setCurrentTime(self.getCurrentTicks());
|
||||
}
|
||||
|
||||
function onPause() {
|
||||
|
||||
Logger.log('audio element event: pause');
|
||||
|
||||
self.onPlaystateChange(this);
|
||||
|
||||
// In the event timeupdate isn't firing, at least we can update when this happens
|
||||
self.setCurrentTime(self.getCurrentTicks());
|
||||
}
|
||||
|
||||
function onPlaying() {
|
||||
Logger.log('audio element event: playing');
|
||||
|
||||
self.onPlaystateChange(this);
|
||||
|
||||
// In the event timeupdate isn't firing, at least we can update when this happens
|
||||
self.setCurrentTime(self.getCurrentTicks());
|
||||
}
|
||||
|
||||
var getItemFields = "MediaSources,Chapters";
|
||||
|
||||
self.tryPair = function (target) {
|
||||
|
|
|
@ -591,8 +591,8 @@
|
|||
|
||||
Events.off(currentPlayer, 'playbackstart', onPlaybackStart);
|
||||
Events.off(currentPlayer, 'playbackstop', onPlaybackStopped);
|
||||
Events.off(currentPlayer, 'volumechange', onStateChanged);
|
||||
Events.off(currentPlayer, 'playstatechange', onVolumeChanged);
|
||||
Events.off(currentPlayer, 'volumechange', onVolumeChanged);
|
||||
Events.off(currentPlayer, 'playstatechange', onStateChanged);
|
||||
Events.off(currentPlayer, 'positionchange', onStateChanged);
|
||||
|
||||
currentPlayer.endPlayerUpdates();
|
||||
|
@ -635,8 +635,8 @@
|
|||
|
||||
Events.on(player, 'playbackstart', onPlaybackStart);
|
||||
Events.on(player, 'playbackstop', onPlaybackStopped);
|
||||
Events.on(player, 'volumechange', onStateChanged);
|
||||
Events.on(player, 'playstatechange', onVolumeChanged);
|
||||
Events.on(player, 'volumechange', onVolumeChanged);
|
||||
Events.on(player, 'playstatechange', onStateChanged);
|
||||
Events.on(player, 'positionchange', onStateChanged);
|
||||
}
|
||||
|
||||
|
|
|
@ -2047,10 +2047,6 @@ var AppInfo = {};
|
|||
deps.push('connectionmanagerfactory');
|
||||
deps.push('credentialprovider');
|
||||
|
||||
if (AppInfo.isNativeApp && browserInfo.android) {
|
||||
require(['cordova/android/logging']);
|
||||
}
|
||||
|
||||
deps.push('appstorage');
|
||||
deps.push('scripts/mediaplayer');
|
||||
deps.push('scripts/appsettings');
|
||||
|
|
|
@ -947,5 +947,6 @@
|
|||
"FreeAppsFeatureDescription": "Enjoy free access to select Emby apps for your devices.",
|
||||
"HeaderCinemaMode": "Cinema Mode",
|
||||
"CinemaModeFeatureDescription": "Cinema Mode gives you the true cinema experience with trailers and custom intros before the feature.",
|
||||
"CoverArt": "Cover Art"
|
||||
"CoverArt": "Cover Art",
|
||||
"ButtonOff": "Off"
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue