mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Add playback rate control for Youtube & Vimeo
This commit is contained in:
parent
4433eefe15
commit
8c69553891
@ -21,6 +21,7 @@ import TextSelectionNode
|
||||
import UrlEscaping
|
||||
import UndoUI
|
||||
import ManagedAnimationNode
|
||||
import TelegramUniversalVideoContent
|
||||
|
||||
private let deleteImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionTrash"), color: .white)
|
||||
private let actionImage = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionForward"), color: .white)
|
||||
@ -593,6 +594,14 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if let media = media as? TelegramMediaWebpage, case let .Loaded(content) = media.content {
|
||||
let type = webEmbedType(content: content)
|
||||
switch type {
|
||||
case .youtube, .vimeo:
|
||||
canFullscreen = true
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -774,6 +774,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
var forceEnablePiP = false
|
||||
var forceEnableUserInteraction = false
|
||||
var isAnimated = false
|
||||
var isEnhancedWebPlayer = false
|
||||
if let content = item.content as? NativeVideoContent {
|
||||
isAnimated = content.fileReference.media.isAnimated
|
||||
self.videoFramePreview = MediaPlayerFramePreview(postbox: item.context.account.postbox, fileReference: content.fileReference)
|
||||
@ -783,9 +784,12 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
let type = webEmbedType(content: content.webpageContent)
|
||||
switch type {
|
||||
case .youtube:
|
||||
isEnhancedWebPlayer = true
|
||||
forceEnableUserInteraction = true
|
||||
disablePictureInPicture = !(item.configuration?.youtubePictureInPictureEnabled ?? false)
|
||||
self.videoFramePreview = YoutubeEmbedFramePreview(context: item.context, content: content)
|
||||
case .vimeo:
|
||||
isEnhancedWebPlayer = true
|
||||
case .iframe:
|
||||
disablePlayerControls = true
|
||||
default:
|
||||
@ -1122,7 +1126,14 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
}
|
||||
}
|
||||
|
||||
if !isWebpage, let file = file, !file.isAnimated {
|
||||
var hasMoreButton = false
|
||||
if isEnhancedWebPlayer {
|
||||
hasMoreButton = true
|
||||
} else if !isWebpage, let file = file, !file.isAnimated {
|
||||
hasMoreButton = true
|
||||
}
|
||||
|
||||
if hasMoreButton {
|
||||
let moreMenuItem = UIBarButtonItem(customDisplayNode: self.moreBarButton)!
|
||||
barButtonItems.append(moreMenuItem)
|
||||
}
|
||||
@ -1316,6 +1327,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
if let time = item.timecode {
|
||||
seek = .timecode(time)
|
||||
}
|
||||
playbackRate = item.playbackRate
|
||||
}
|
||||
}
|
||||
videoNode.setBaseRate(playbackRate)
|
||||
@ -1922,7 +1934,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
}
|
||||
}
|
||||
|
||||
private func contentInfo() -> (message: Message, file: TelegramMediaFile, isWebpage: Bool)? {
|
||||
private func contentInfo() -> (message: Message, file: TelegramMediaFile?, isWebpage: Bool)? {
|
||||
guard let item = self.item else {
|
||||
return nil
|
||||
}
|
||||
@ -1933,16 +1945,15 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
if let m = m as? TelegramMediaFile, m.isVideo {
|
||||
file = m
|
||||
break
|
||||
} else if let m = m as? TelegramMediaWebpage, case let .Loaded(content) = m.content, let f = content.file, f.isVideo {
|
||||
file = f
|
||||
} else if let m = m as? TelegramMediaWebpage, case let .Loaded(content) = m.content {
|
||||
if let f = content.file, f.isVideo {
|
||||
file = f
|
||||
}
|
||||
isWebpage = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if let file = file {
|
||||
return (message, file, isWebpage)
|
||||
}
|
||||
return (message, file, isWebpage)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -2041,7 +2052,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
|
||||
c.setItems(strongSelf.contextMenuSpeedItems())
|
||||
})))
|
||||
if let (message, file, isWebpage) = strongSelf.contentInfo(), !isWebpage {
|
||||
if let (message, maybeFile, isWebpage) = strongSelf.contentInfo(), let file = maybeFile, !isWebpage {
|
||||
items.append(.action(ContextMenuActionItem(text: "Save to Gallery", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Download"), color: theme.actionSheet.primaryTextColor) }, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
|
@ -282,17 +282,7 @@
|
||||
} completion:nil];
|
||||
};
|
||||
[self addSubview:_zoomView];
|
||||
|
||||
_flashControl.becameActive = ^
|
||||
{
|
||||
__strong TGCameraMainPhoneView *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
|
||||
if (strongSelf->_modeControl.cameraMode == PGCameraModeVideo)
|
||||
[strongSelf->_timecodeView setHidden:true animated:true];
|
||||
};
|
||||
|
||||
_flashControl.modeChanged = ^(PGCameraFlashMode mode)
|
||||
{
|
||||
__strong TGCameraMainPhoneView *strongSelf = weakSelf;
|
||||
@ -301,9 +291,6 @@
|
||||
|
||||
if (strongSelf.flashModeChanged != nil)
|
||||
strongSelf.flashModeChanged(mode);
|
||||
|
||||
if (strongSelf->_modeControl.cameraMode == PGCameraModeVideo)
|
||||
[strongSelf->_timecodeView setHidden:false animated:true];
|
||||
};
|
||||
|
||||
_modeControl.modeChanged = ^(PGCameraMode mode, PGCameraMode previousMode)
|
||||
|
@ -9,14 +9,10 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<iframe id="player" src="https://player.vimeo.com/video/%@?api=1&badge=0&byline=0&portrait=0&title=0&player_id=player" width="100%" height="100%" frameborder="0"></iframe>
|
||||
<iframe id="player" src="https://player.vimeo.com/video/%@?badge=0&byline=0&portrait=0&title=0" width="100%" height="100%" frameborder="0"></iframe>
|
||||
</div>
|
||||
<script src="https://player.vimeo.com/api/player.js"></script>
|
||||
<script>
|
||||
var Froogaloop=function(){function e(a){return new e.fn.init(a)}function g(a,c,b){if(!b.contentWindow.postMessage)return!1;a=JSON.stringify({method:a,value:c});b.contentWindow.postMessage(a,h)}function l(a){var c,b;try{c=JSON.parse(a.data),b=c.event||c.method}catch(e){}"ready"!=b||k||(k=!0);if(!/^https?:\/\/player.vimeo.com/.test(a.origin))return!1;"*"===h&&(h=a.origin);a=c.value;var m=c.data,f=""===f?null:c.player_id;c=f?d[f][b]:d[b];b=[];if(!c)return!1;void 0!==a&&b.push(a);m&&b.push(m);f&&b.push(f);
|
||||
return 0<b.length?c.apply(null,b):c.call()}function n(a,c,b){b?(d[b]||(d[b]={}),d[b][a]=c):d[a]=c}var d={},k=!1,h="*";e.fn=e.prototype={element:null,init:function(a){"string"===typeof a&&(a=document.getElementById(a));this.element=a;return this},api:function(a,c){if(!this.element||!a)return!1;var b=this.element,d=""!==b.id?b.id:null,e=c&&c.constructor&&c.call&&c.apply?null:c,f=c&&c.constructor&&c.call&&c.apply?c:null;f&&n(a,f,d);g(a,e,b);return this},addEvent:function(a,c){if(!this.element)return!1;
|
||||
var b=this.element,d=""!==b.id?b.id:null;n(a,c,d);"ready"!=a?g("addEventListener",a,b):"ready"==a&&k&&c.call(null,d);return this},removeEvent:function(a){if(!this.element)return!1;var c=this.element,b=""!==c.id?c.id:null;a:{if(b&&d[b]){if(!d[b][a]){b=!1;break a}d[b][a]=null}else{if(!d[a]){b=!1;break a}d[a]=null}b=!0}"ready"!=a&&b&&g("removeEventListener",a,c)}};e.fn.init.prototype=e.fn;window.addEventListener?window.addEventListener("message",l,!1):window.attachEvent("onmessage",l);return window.Froogaloop=
|
||||
window.$f=e}();
|
||||
|
||||
var iframe;
|
||||
var player;
|
||||
function invoke(command) {
|
||||
@ -26,7 +22,7 @@
|
||||
var played = false;
|
||||
function play() {
|
||||
if (played) {
|
||||
player.api("play");
|
||||
player.play();
|
||||
} else {
|
||||
invoke("autoplay");
|
||||
played = true;
|
||||
@ -34,44 +30,46 @@
|
||||
}
|
||||
|
||||
function pause() {
|
||||
player.api("pause");
|
||||
player.pause();
|
||||
}
|
||||
|
||||
function seek(timestamp) {
|
||||
player.api("seekTo", timestamp);
|
||||
player.setCurrentTime(timestamp)
|
||||
}
|
||||
|
||||
function setRate(rate) {
|
||||
player.setPlaybackRate(rate)
|
||||
}
|
||||
|
||||
(function() {
|
||||
var playbackState = 0;
|
||||
var playbackState = 1;
|
||||
var duration = 0.0;
|
||||
var position = 0.0;
|
||||
var downloadProgress = 0.0;
|
||||
|
||||
iframe = document.querySelectorAll("iframe")[0];
|
||||
player = $f(iframe);
|
||||
|
||||
function updateState() {
|
||||
window.location.href = "embed://onState?playback=" + playbackState + "&position=" + position + "&duration=" + duration + "&download=" + downloadProgress;
|
||||
}
|
||||
|
||||
player.addEvent("ready", function(player_id) {
|
||||
window.location.href = "embed://onReady?data=" + player_id;
|
||||
|
||||
player.addEvent("play", onPlay);
|
||||
player.addEvent("pause", onPause);
|
||||
player.addEvent("finish", onFinish);
|
||||
player.addEvent("playProgress", onPlayProgress);
|
||||
player.addEvent("loadProgress", onLoadProgress);
|
||||
|
||||
window.setInterval(updateState, 500);
|
||||
|
||||
invoke("initialize");
|
||||
|
||||
if (%@) {
|
||||
invoke("autoplay");
|
||||
}
|
||||
player = new Vimeo.Player(iframe);
|
||||
player.getCurrentTime().then(function(seconds) {
|
||||
position = seconds;
|
||||
});
|
||||
|
||||
player.getDuration().then(function(seconds) {
|
||||
duration = seconds;
|
||||
});
|
||||
|
||||
function updateState() {
|
||||
player.getPaused().then(function(paused) {
|
||||
playbackState = paused ? 0 : 1;
|
||||
});
|
||||
player.getCurrentTime().then(function(seconds) {
|
||||
position = seconds;
|
||||
});
|
||||
player.getDuration().then(function(seconds) {
|
||||
duration = seconds;
|
||||
});
|
||||
window.location.href = "embed://onState?playback=" + playbackState + "&position=" + position + "&duration=" + duration + "&download=" + downloadProgress;
|
||||
invoke("initialize");
|
||||
}
|
||||
|
||||
function onPlay(data) {
|
||||
playbackState = 1;
|
||||
updateState();
|
||||
@ -95,6 +93,16 @@
|
||||
function onLoadProgress(data) {
|
||||
downloadProgress = data.percent;
|
||||
}
|
||||
|
||||
player.on('play', onPlay);
|
||||
player.on('pause', onPause);
|
||||
player.on("ended", onFinish);
|
||||
|
||||
window.setInterval(updateState, 500);
|
||||
|
||||
if (%@) {
|
||||
invoke("autoplay");
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
|
@ -4,17 +4,17 @@ function initialize() {
|
||||
controls.style.display = "none";
|
||||
}
|
||||
|
||||
var sidedock = document.getElementsByClassName("sidedock")[0];
|
||||
var sidedock = document.getElementsByClassName("vp-sidedock")[0];
|
||||
if (sidedock != null) {
|
||||
sidedock.style.display = "none";
|
||||
}
|
||||
|
||||
var video = document.getElementsByTagName("video")[0];
|
||||
if (video != null) {
|
||||
video.setAttribute("webkit-playsinline", "");
|
||||
video.setAttribute("playsinline", "");
|
||||
video.webkitEnterFullscreen = undefined;
|
||||
}
|
||||
// var video = document.getElementsByTagName("video")[0];
|
||||
// if (video != null) {
|
||||
// video.setAttribute("webkit-playsinline", "");
|
||||
// video.setAttribute("playsinline", "");
|
||||
// video.webkitEnterFullscreen = undefined;
|
||||
// }
|
||||
}
|
||||
|
||||
function eventFire(el, etype){
|
||||
|
@ -60,6 +60,10 @@
|
||||
player.seekTo(timestamp, true);
|
||||
}
|
||||
|
||||
function setRate(rate) {
|
||||
player.setPlaybackRate(rate);
|
||||
}
|
||||
|
||||
function updateState() {
|
||||
window.location.href = "embed://onState?failed=" + failed + "&playback=" + playbackState + "&position=" + position + "&duration=" + duration + "&download=" + downloadProgress + '&quality=' + quality + '&availableQualities=' + availableQualities + '&storyboard=' + storyboardSpec;
|
||||
}
|
||||
|
@ -71,6 +71,9 @@ final class GenericEmbedImplementation: WebEmbedImplementation {
|
||||
func seek(timestamp: Double) {
|
||||
}
|
||||
|
||||
func setBaseRate(_ baseRate: Double) {
|
||||
}
|
||||
|
||||
func pageReady() {
|
||||
self.status = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: 0, status: .playing, soundEnabled: true)
|
||||
self.updateStatus?(self.status)
|
||||
|
@ -88,6 +88,9 @@ final class TwitchEmbedImplementation: WebEmbedImplementation {
|
||||
func seek(timestamp: Double) {
|
||||
}
|
||||
|
||||
func setBaseRate(_ baseRate: Double) {
|
||||
}
|
||||
|
||||
func pageReady() {
|
||||
// Queue.mainQueue().after(delay: 0.5) {
|
||||
// if let onPlaybackStarted = self.onPlaybackStarted {
|
||||
|
@ -88,6 +88,7 @@ final class VimeoEmbedImplementation: WebEmbedImplementation {
|
||||
|
||||
private let videoId: String
|
||||
private let timestamp: Int
|
||||
private var baseRate: Double = 1.0
|
||||
private var status : MediaPlayerStatus
|
||||
|
||||
private var ready: Bool = false
|
||||
@ -160,12 +161,30 @@ final class VimeoEmbedImplementation: WebEmbedImplementation {
|
||||
eval("seek(\(timestamp));", nil)
|
||||
}
|
||||
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: self.status.duration, dimensions: self.status.dimensions, timestamp: timestamp, baseRate: 1.0, seekId: self.status.seekId + 1, status: self.status.status, soundEnabled: self.status.soundEnabled)
|
||||
if let updateStatus = self.updateStatus {
|
||||
updateStatus(self.status)
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: self.status.duration, dimensions: self.status.dimensions, timestamp: timestamp, baseRate: self.status.baseRate, seekId: self.status.seekId + 1, status: self.status.status, soundEnabled: self.status.soundEnabled)
|
||||
self.updateStatus?(self.status)
|
||||
|
||||
self.ignorePosition = 2
|
||||
}
|
||||
|
||||
func setBaseRate(_ baseRate: Double) {
|
||||
var baseRate = baseRate
|
||||
if baseRate < 0.5 {
|
||||
baseRate = 0.5
|
||||
}
|
||||
if baseRate > 2.0 {
|
||||
baseRate = 2.0
|
||||
}
|
||||
if !self.ready {
|
||||
self.baseRate = baseRate
|
||||
}
|
||||
|
||||
self.ignorePosition = 2
|
||||
if let eval = self.evalImpl {
|
||||
eval("setRate(\(baseRate));", nil)
|
||||
}
|
||||
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: self.status.duration, dimensions: self.status.dimensions, timestamp: self.status.timestamp, baseRate: baseRate, seekId: self.status.seekId + 1, status: self.status.status, soundEnabled: true)
|
||||
self.updateStatus?(self.status)
|
||||
}
|
||||
|
||||
func pageReady() {
|
||||
@ -210,6 +229,11 @@ final class VimeoEmbedImplementation: WebEmbedImplementation {
|
||||
}
|
||||
}
|
||||
|
||||
if !self.ready {
|
||||
self.ready = true
|
||||
self.play()
|
||||
}
|
||||
|
||||
if let updateStatus = self.updateStatus, let playback = playback, let duration = duration {
|
||||
let playbackStatus: MediaPlayerPlaybackStatus
|
||||
switch playback {
|
||||
@ -226,10 +250,12 @@ final class VimeoEmbedImplementation: WebEmbedImplementation {
|
||||
|
||||
if case .playing = playbackStatus, !self.started {
|
||||
self.started = true
|
||||
self.onPlaybackStarted?()
|
||||
Queue.mainQueue().after(0.5) {
|
||||
self.onPlaybackStarted?()
|
||||
}
|
||||
}
|
||||
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: Double(duration), dimensions: self.status.dimensions, timestamp: newTimestamp, baseRate: 1.0, seekId: self.status.seekId, status: playbackStatus, soundEnabled: true)
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: Double(duration), dimensions: self.status.dimensions, timestamp: newTimestamp, baseRate: self.status.baseRate, seekId: self.status.seekId, status: playbackStatus, soundEnabled: true)
|
||||
updateStatus(self.status)
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ protocol WebEmbedImplementation {
|
||||
func pause()
|
||||
func togglePlayPause()
|
||||
func seek(timestamp: Double)
|
||||
func setBaseRate(_ baseRate: Double)
|
||||
|
||||
func pageReady()
|
||||
func callback(url: URL)
|
||||
@ -170,6 +171,10 @@ final class WebEmbedPlayerNode: ASDisplayNode, WKNavigationDelegate {
|
||||
self.impl.seek(timestamp: timestamp)
|
||||
}
|
||||
|
||||
func setBaseRate(_ baseRate: Double) {
|
||||
self.impl.setBaseRate(baseRate)
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
|
||||
}
|
||||
|
||||
|
@ -172,6 +172,7 @@ final class WebEmbedVideoContentNode: ASDisplayNode, UniversalVideoContentNode {
|
||||
}
|
||||
|
||||
func setBaseRate(_ baseRate: Double) {
|
||||
self.playerNode.setBaseRate(baseRate)
|
||||
}
|
||||
|
||||
func addPlaybackCompleted(_ f: @escaping () -> Void) -> Int {
|
||||
|
@ -100,6 +100,7 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
}
|
||||
|
||||
private var timestamp: Int
|
||||
private var baseRate: Double = 1.0
|
||||
private var ignoreEarlierTimestamps = false
|
||||
private var status: MediaPlayerStatus
|
||||
|
||||
@ -107,6 +108,8 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
private var started = false
|
||||
private var ignorePosition: Int?
|
||||
|
||||
private var isPlaying = true
|
||||
|
||||
private enum PlaybackDelay {
|
||||
case none
|
||||
case afterPositionUpdates(count: Int)
|
||||
@ -186,6 +189,8 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
return
|
||||
}
|
||||
|
||||
self.isPlaying = true
|
||||
|
||||
if let eval = self.evalImpl {
|
||||
eval("play();", nil)
|
||||
}
|
||||
@ -194,6 +199,7 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
}
|
||||
|
||||
func pause() {
|
||||
self.isPlaying = false
|
||||
if let eval = self.evalImpl {
|
||||
eval("pause();", nil)
|
||||
}
|
||||
@ -201,9 +207,9 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
|
||||
func togglePlayPause() {
|
||||
if case .playing = self.status.status {
|
||||
pause()
|
||||
self.pause()
|
||||
} else {
|
||||
play()
|
||||
self.play()
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,12 +223,32 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
eval("seek(\(timestamp));", nil)
|
||||
}
|
||||
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: self.status.duration, dimensions: self.status.dimensions, timestamp: timestamp, baseRate: 1.0, seekId: self.status.seekId + 1, status: self.status.status, soundEnabled: true)
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: self.status.duration, dimensions: self.status.dimensions, timestamp: timestamp, baseRate: self.status.baseRate, seekId: self.status.seekId + 1, status: self.status.status, soundEnabled: true)
|
||||
self.updateStatus?(self.status)
|
||||
|
||||
self.ignorePosition = 2
|
||||
}
|
||||
|
||||
func setBaseRate(_ baseRate: Double) {
|
||||
var baseRate = baseRate
|
||||
if baseRate < 0.5 {
|
||||
baseRate = 0.5
|
||||
}
|
||||
if baseRate > 2.0 {
|
||||
baseRate = 2.0
|
||||
}
|
||||
if !self.ready {
|
||||
self.baseRate = baseRate
|
||||
}
|
||||
|
||||
if let eval = self.evalImpl {
|
||||
eval("setRate(\(baseRate));", nil)
|
||||
}
|
||||
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: self.status.duration, dimensions: self.status.dimensions, timestamp: self.status.timestamp, baseRate: baseRate, seekId: self.status.seekId + 1, status: self.status.status, soundEnabled: true)
|
||||
self.updateStatus?(self.status)
|
||||
}
|
||||
|
||||
func pageReady() {
|
||||
}
|
||||
|
||||
@ -283,6 +309,7 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
switch playback {
|
||||
case 0:
|
||||
if newTimestamp > Double(duration) - 1.0 {
|
||||
self.isPlaying = false
|
||||
playbackStatus = .paused
|
||||
newTimestamp = 0.0
|
||||
} else {
|
||||
@ -293,9 +320,9 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
case 2:
|
||||
playbackStatus = .paused
|
||||
case 3:
|
||||
playbackStatus = .buffering(initial: false, whilePlaying: true, progress: 0.0, display: false)
|
||||
playbackStatus = .buffering(initial: !self.started, whilePlaying: self.isPlaying, progress: 0.0, display: false)
|
||||
default:
|
||||
playbackStatus = .buffering(initial: true, whilePlaying: false, progress: 0.0, display: false)
|
||||
playbackStatus = .buffering(initial: true, whilePlaying: true, progress: 0.0, display: false)
|
||||
}
|
||||
|
||||
if case .playing = playbackStatus, !self.started {
|
||||
@ -305,7 +332,7 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
self.onPlaybackStarted?()
|
||||
}
|
||||
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: Double(duration), dimensions: self.status.dimensions, timestamp: newTimestamp, baseRate: 1.0, seekId: self.status.seekId, status: playbackStatus, soundEnabled: true)
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: Double(duration), dimensions: self.status.dimensions, timestamp: newTimestamp, baseRate: self.status.baseRate, seekId: self.status.seekId, status: playbackStatus, soundEnabled: true)
|
||||
updateStatus(self.status)
|
||||
}
|
||||
}
|
||||
@ -327,12 +354,20 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
self.play()
|
||||
}
|
||||
|
||||
if self.baseRate != 1.0 {
|
||||
self.setBaseRate(self.baseRate)
|
||||
}
|
||||
|
||||
print("YT ready in \(CFAbsoluteTimeGetCurrent() - self.benchmarkStartTime)")
|
||||
|
||||
Queue.mainQueue().async {
|
||||
self.play()
|
||||
|
||||
let delay = self.timestamp > 0 ? 2.8 : 2.0
|
||||
if self.timestamp > 0 {
|
||||
self.seek(timestamp: Double(self.timestamp))
|
||||
self.play()
|
||||
} else {
|
||||
self.play()
|
||||
}
|
||||
Queue.mainQueue().after(delay, {
|
||||
if !self.started {
|
||||
self.play()
|
||||
|
Loading…
x
Reference in New Issue
Block a user