mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Add twitch embed player wrapper
This commit is contained in:
parent
401b8c2922
commit
8e60dc4da3
@ -25,12 +25,8 @@
|
||||
};
|
||||
})();
|
||||
|
||||
function play() {
|
||||
invoke("play");
|
||||
}
|
||||
|
||||
function pause() {
|
||||
invoke("play");
|
||||
function playPause() {
|
||||
invoke("playPause");
|
||||
}
|
||||
|
||||
function receiveMessage(evt) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
function initialize() {
|
||||
var controls = document.getElementsByClassName("player-controls-bottom")[0];
|
||||
var controls = document.getElementsByClassName("pl-controls-bottom")[0];
|
||||
if (controls == null) {
|
||||
controls = document.getElementsByClassName("player-overlay-container")[0];
|
||||
}
|
||||
@ -7,9 +7,14 @@ function initialize() {
|
||||
controls.style.display = "none";
|
||||
}
|
||||
|
||||
var root = document.getElementsByClassName("player-root")[0];
|
||||
if (root != null) {
|
||||
root.style.display = "none";
|
||||
}
|
||||
|
||||
var topBar = document.getElementById("top-bar");
|
||||
if (topBar == null) {
|
||||
topBar = document.getElementsByClassName("player-controls-top")[0];
|
||||
topBar = document.getElementsByClassName("pl-controls-top")[0];
|
||||
}
|
||||
if (topBar != null) {
|
||||
topBar.style.display = "none";
|
||||
@ -17,7 +22,7 @@ function initialize() {
|
||||
|
||||
var pauseOverlay = document.getElementsByClassName("player-play-overlay")[0];
|
||||
if (pauseOverlay == null) {
|
||||
pauseOverlay = document.getElementsByClassName("player-controls-bottom")[0];
|
||||
pauseOverlay = document.getElementsByClassName("pl-controls-bottom")[0];
|
||||
}
|
||||
if (pauseOverlay != null) {
|
||||
pauseOverlay.style.display = "none";
|
||||
@ -85,13 +90,15 @@ function eventFire(el, etype){
|
||||
}
|
||||
}
|
||||
|
||||
function play() {
|
||||
function togglePlayPause() {
|
||||
var playButton = document.getElementsByClassName("js-control-playpause-button")[0];
|
||||
if (playButton == null) {
|
||||
playButton = document.getElementsByClassName("player-button--playpause")[0];
|
||||
playButton = document.getElementsByClassName("player-button")[0];
|
||||
}
|
||||
|
||||
eventFire(playButton, "click");
|
||||
if (playButton != null) {
|
||||
eventFire(playButton, "click");
|
||||
}
|
||||
}
|
||||
|
||||
function receiveMessage(evt) {
|
||||
@ -105,8 +112,8 @@ function receiveMessage(evt) {
|
||||
|
||||
if (obj.command == "initialize")
|
||||
initialize();
|
||||
else if (obj.command == "play")
|
||||
play();
|
||||
else if (obj.command == "playPause")
|
||||
togglePlayPause();
|
||||
} catch (ex) { }
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,117 @@
|
||||
import Foundation
|
||||
import WebKit
|
||||
import SwiftSignalKit
|
||||
import UniversalMediaPlayer
|
||||
import AppBundle
|
||||
|
||||
func isTwitchVideoUrl(_ url: String) -> Bool {
|
||||
return url.contains("//player.twitch.tv/") || url.contains("//clips.twitch.tv/")
|
||||
}
|
||||
|
||||
final class TwitchEmbedImplementation: WebEmbedImplementation {
|
||||
private var evalImpl: ((String) -> Void)?
|
||||
private var updateStatus: ((MediaPlayerStatus) -> Void)?
|
||||
private var onPlaybackStarted: (() -> Void)?
|
||||
|
||||
private let url: String
|
||||
private var status : MediaPlayerStatus
|
||||
|
||||
private var started = false
|
||||
|
||||
init(url: String) {
|
||||
self.url = url
|
||||
self.status = MediaPlayerStatus(generationTimestamp: 0.0, duration: 0.0, dimensions: CGSize(), timestamp: 0.0, baseRate: 1.0, seekId: 0, status: .buffering(initial: true, whilePlaying: true), soundEnabled: true)
|
||||
}
|
||||
|
||||
func setup(_ webView: WKWebView, userContentController: WKUserContentController, evaluateJavaScript: @escaping (String) -> Void, updateStatus: @escaping (MediaPlayerStatus) -> Void, onPlaybackStarted: @escaping () -> Void) {
|
||||
let bundle = getAppBundle()
|
||||
guard let userScriptPath = bundle.path(forResource: "TwitchUserScript", ofType: "js") else {
|
||||
return
|
||||
}
|
||||
guard let userScriptData = try? Data(contentsOf: URL(fileURLWithPath: userScriptPath)) else {
|
||||
return
|
||||
}
|
||||
guard let userScript = String(data: userScriptData, encoding: .utf8) else {
|
||||
return
|
||||
}
|
||||
guard let htmlTemplatePath = bundle.path(forResource: "Twitch", ofType: "html") else {
|
||||
return
|
||||
}
|
||||
guard let htmlTemplateData = try? Data(contentsOf: URL(fileURLWithPath: htmlTemplatePath)) else {
|
||||
return
|
||||
}
|
||||
guard let htmlTemplate = String(data: htmlTemplateData, encoding: .utf8) else {
|
||||
return
|
||||
}
|
||||
|
||||
self.evalImpl = evaluateJavaScript
|
||||
self.updateStatus = updateStatus
|
||||
self.onPlaybackStarted = onPlaybackStarted
|
||||
updateStatus(self.status)
|
||||
|
||||
let html = String(format: htmlTemplate, self.url)
|
||||
webView.loadHTMLString(html, baseURL: URL(string: "about:blank"))
|
||||
|
||||
userContentController.addUserScript(WKUserScript(source: userScript, injectionTime: .atDocumentEnd, forMainFrameOnly: false))
|
||||
}
|
||||
|
||||
func play() {
|
||||
if let eval = self.evalImpl {
|
||||
eval("playPause()")
|
||||
}
|
||||
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: self.status.duration, dimensions: self.status.dimensions, timestamp: self.status.timestamp, baseRate: 1.0, seekId: self.status.seekId, status: .playing, soundEnabled: self.status.soundEnabled)
|
||||
if let updateStatus = self.updateStatus {
|
||||
updateStatus(self.status)
|
||||
}
|
||||
}
|
||||
|
||||
func pause() {
|
||||
if let eval = self.evalImpl {
|
||||
eval("playPause()")
|
||||
}
|
||||
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: self.status.duration, dimensions: self.status.dimensions, timestamp: self.status.timestamp, baseRate: 1.0, seekId: self.status.seekId, status: .paused, soundEnabled: self.status.soundEnabled)
|
||||
if let updateStatus = self.updateStatus {
|
||||
updateStatus(self.status)
|
||||
}
|
||||
}
|
||||
|
||||
func togglePlayPause() {
|
||||
if self.status.status == .playing {
|
||||
self.pause()
|
||||
} else {
|
||||
self.play()
|
||||
}
|
||||
}
|
||||
|
||||
func seek(timestamp: Double) {
|
||||
}
|
||||
|
||||
func pageReady() {
|
||||
// Queue.mainQueue().after(delay: 0.5) {
|
||||
// if let onPlaybackStarted = self.onPlaybackStarted {
|
||||
// onPlaybackStarted()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
func callback(url: URL) {
|
||||
switch url.host {
|
||||
case "onPlayback":
|
||||
if !self.started {
|
||||
self.started = true
|
||||
self.status = MediaPlayerStatus(generationTimestamp: self.status.generationTimestamp, duration: self.status.duration, dimensions: self.status.dimensions, timestamp: self.status.timestamp, baseRate: 1.0, seekId: self.status.seekId, status: .playing, soundEnabled: self.status.soundEnabled)
|
||||
if let updateStatus = self.updateStatus {
|
||||
updateStatus(self.status)
|
||||
}
|
||||
|
||||
if let onPlaybackStarted = self.onPlaybackStarted {
|
||||
onPlaybackStarted()
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
@ -134,7 +134,7 @@ final class VimeoEmbedImplementation: WebEmbedImplementation {
|
||||
}
|
||||
|
||||
func play() {
|
||||
if let eval = evalImpl {
|
||||
if let eval = self.evalImpl {
|
||||
eval("play();")
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ final class VimeoEmbedImplementation: WebEmbedImplementation {
|
||||
}
|
||||
|
||||
func pause() {
|
||||
if let eval = evalImpl {
|
||||
if let eval = self.evalImpl {
|
||||
eval("pause();")
|
||||
}
|
||||
}
|
||||
@ -156,7 +156,7 @@ final class VimeoEmbedImplementation: WebEmbedImplementation {
|
||||
}
|
||||
|
||||
func seek(timestamp: Double) {
|
||||
if let eval = evalImpl {
|
||||
if let eval = self.evalImpl {
|
||||
eval("seek(\(timestamp));")
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ final class VimeoEmbedImplementation: WebEmbedImplementation {
|
||||
updateStatus(self.status)
|
||||
}
|
||||
|
||||
ignorePosition = 2
|
||||
self.ignorePosition = 2
|
||||
}
|
||||
|
||||
func pageReady() {
|
||||
|
@ -22,6 +22,7 @@ protocol WebEmbedImplementation {
|
||||
public enum WebEmbedType {
|
||||
case youtube(videoId: String, timestamp: Int)
|
||||
case vimeo(videoId: String, timestamp: Int)
|
||||
case twitch(url: String)
|
||||
case iframe(url: String)
|
||||
|
||||
public var supportsSeeking: Bool {
|
||||
@ -37,6 +38,10 @@ public enum WebEmbedType {
|
||||
public func webEmbedType(content: TelegramMediaWebpageLoadedContent, forcedTimestamp: Int? = nil) -> WebEmbedType {
|
||||
if let (videoId, timestamp) = extractYoutubeVideoIdAndTimestamp(url: content.url) {
|
||||
return .youtube(videoId: videoId, timestamp: forcedTimestamp ?? timestamp)
|
||||
} else if let (videoId, timestamp) = extractVimeoVideoIdAndTimestamp(url: content.url) {
|
||||
return .vimeo(videoId: videoId, timestamp: forcedTimestamp ?? timestamp)
|
||||
} else if let embedUrl = content.embedUrl, isTwitchVideoUrl(embedUrl) {
|
||||
return .twitch(url: embedUrl)
|
||||
} else {
|
||||
return .iframe(url: content.embedUrl ?? content.url)
|
||||
}
|
||||
@ -48,6 +53,8 @@ func webEmbedImplementation(for type: WebEmbedType) -> WebEmbedImplementation {
|
||||
return YoutubeEmbedImplementation(videoId: videoId, timestamp: timestamp)
|
||||
case let .vimeo(videoId, timestamp):
|
||||
return VimeoEmbedImplementation(videoId: videoId, timestamp: timestamp)
|
||||
case let .twitch(url):
|
||||
return TwitchEmbedImplementation(url: url)
|
||||
case let .iframe(url):
|
||||
return GenericEmbedImplementation(url: url)
|
||||
}
|
||||
|
@ -93,8 +93,8 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
private var ignoreEarlierTimestamps = false
|
||||
private var status : MediaPlayerStatus
|
||||
|
||||
private var ready: Bool = false
|
||||
private var started: Bool = false
|
||||
private var ready = false
|
||||
private var started = false
|
||||
private var ignorePosition: Int?
|
||||
|
||||
private enum PlaybackDelay {
|
||||
@ -176,7 +176,7 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
return
|
||||
}
|
||||
|
||||
if let eval = evalImpl {
|
||||
if let eval = self.evalImpl {
|
||||
eval("play();")
|
||||
}
|
||||
|
||||
@ -184,7 +184,7 @@ final class YoutubeEmbedImplementation: WebEmbedImplementation {
|
||||
}
|
||||
|
||||
func pause() {
|
||||
if let eval = evalImpl {
|
||||
if let eval = self.evalImpl {
|
||||
eval("pause();")
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user