Merge branch 'main' into PangMo5/coordinator-and-deep-link

This commit is contained in:
Kwangmin Bae 2021-08-22 05:26:05 +09:00 committed by GitHub
commit 4d6ca79d6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 85 additions and 73 deletions

View File

@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19115.3" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_5" orientation="landscape" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19107.5"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="Image references" minToolsVersion="12.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
@ -30,7 +29,7 @@
<rect key="frame" x="0.0" y="0.0" width="896" height="414"/>
<subviews>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="e9f-8l-RdN" userLabel="SeekSlider">
<rect key="frame" x="50" y="355" width="689" height="31"/>
<rect key="frame" x="133" y="355" width="630" height="31"/>
<color key="tintColor" red="0.66666666666666663" green="0.36078431372549019" blue="0.76470588235294112" alpha="1" colorSpace="calibratedRGB"/>
<color key="thumbTintColor" red="0.66666666666666663" green="0.36078431372549019" blue="0.76470588235294112" alpha="1" colorSpace="calibratedRGB"/>
<connections>
@ -39,7 +38,7 @@
<action selector="seekSliderValueChanged:" destination="Y6W-OH-hqX" eventType="valueChanged" id="tfF-Zl-CdU"/>
</connections>
</slider>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="-:--:--" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qft-iu-f1z">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="-:--:--" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qft-iu-f1z" userLabel="Time Left Text">
<rect key="frame" x="766" y="353" width="91" height="34"/>
<constraints>
<constraint firstAttribute="width" constant="91" id="LbL-h0-EYA"/>
@ -49,6 +48,16 @@
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="-:--:--" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="knf-PP-UIS" userLabel="Time Text">
<rect key="frame" x="39" y="353" width="91" height="34"/>
<constraints>
<constraint firstAttribute="width" constant="91" id="FcP-Mk-OIL"/>
<constraint firstAttribute="height" constant="34" id="yXx-PI-kXn"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="18"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="t2L-Oz-fe9" userLabel="MainActionButton">
<rect key="frame" x="406.66666666666669" y="165.66666666666666" width="83" height="83"/>
<constraints>
@ -156,13 +165,16 @@
<constraint firstItem="o8N-R1-DhT" firstAttribute="centerY" secondItem="riN-y1-ABZ" secondAttribute="centerY" id="Hs5-Bc-iPB"/>
<constraint firstAttribute="bottom" secondItem="qft-iu-f1z" secondAttribute="bottom" constant="27" id="NPi-py-0qd"/>
<constraint firstItem="rLx-SN-RHr" firstAttribute="leading" secondItem="Qcb-Fb-qZl" secondAttribute="leading" constant="30" id="Oe7-LK-6Tl"/>
<constraint firstItem="e9f-8l-RdN" firstAttribute="leading" secondItem="knf-PP-UIS" secondAttribute="trailing" constant="5" id="ShK-80-ij1"/>
<constraint firstItem="t2L-Oz-fe9" firstAttribute="centerY" secondItem="Qcb-Fb-qZl" secondAttribute="centerY" id="TOk-sG-UXV"/>
<constraint firstItem="knf-PP-UIS" firstAttribute="leading" secondItem="Qcb-Fb-qZl" secondAttribute="leading" constant="39" id="XNC-Q4-nE0"/>
<constraint firstItem="o8N-R1-DhT" firstAttribute="centerX" secondItem="t2L-Oz-fe9" secondAttribute="centerX" id="a5g-8U-9S5"/>
<constraint firstAttribute="bottom" secondItem="qft-iu-f1z" secondAttribute="bottom" constant="27" id="aOB-Uz-cbQ"/>
<constraint firstItem="qft-iu-f1z" firstAttribute="leading" secondItem="e9f-8l-RdN" secondAttribute="trailing" constant="29" id="auL-Vv-ZMV"/>
<constraint firstItem="qft-iu-f1z" firstAttribute="leading" secondItem="e9f-8l-RdN" secondAttribute="trailing" constant="5" id="auL-Vv-ZMV"/>
<constraint firstItem="bYM-Xp-bZO" firstAttribute="top" secondItem="An8-jF-FAY" secondAttribute="top" id="cVS-eI-vv2"/>
<constraint firstItem="e9f-8l-RdN" firstAttribute="leading" secondItem="Qcb-Fb-qZl" secondAttribute="leading" constant="52" id="ed3-xq-0Ug"/>
<constraint firstItem="t2L-Oz-fe9" firstAttribute="leading" secondItem="bYM-Xp-bZO" secondAttribute="trailing" constant="118.5" id="fci-L5-1f6"/>
<constraint firstItem="e9f-8l-RdN" firstAttribute="centerX" secondItem="Qcb-Fb-qZl" secondAttribute="centerX" id="jFy-Sb-aYi"/>
<constraint firstAttribute="bottom" secondItem="knf-PP-UIS" secondAttribute="bottom" constant="27" id="nLN-ju-9qC"/>
<constraint firstItem="o8N-R1-DhT" firstAttribute="leading" secondItem="rLx-SN-RHr" secondAttribute="trailing" constant="16" id="qnV-Qf-y9m"/>
<constraint firstItem="rLx-SN-RHr" firstAttribute="top" secondItem="Qcb-Fb-qZl" secondAttribute="top" constant="22" id="v4G-B1-7y6"/>
</constraints>
@ -197,7 +209,8 @@
<outlet property="mainActionButton" destination="t2L-Oz-fe9" id="nQR-2e-64l"/>
<outlet property="playerSettingsButton" destination="riN-y1-ABZ" id="I6r-z9-Jy2"/>
<outlet property="seekSlider" destination="e9f-8l-RdN" id="b3H-tn-TPG"/>
<outlet property="timeText" destination="qft-iu-f1z" id="pAX-J3-I53"/>
<outlet property="timeLeftText" destination="qft-iu-f1z" id="cSg-fO-9nF"/>
<outlet property="timeText" destination="knf-PP-UIS" id="KhK-BX-rqT"/>
<outlet property="titleLabel" destination="o8N-R1-DhT" id="E7D-iU-bMi"/>
<outlet property="upNextView" destination="CY9-gw-dv8" id="BP6-bc-6Vk"/>
<outlet property="videoContentView" destination="Tsh-rC-BwO" id="5uR-No-wLy"/>

View File

@ -38,6 +38,7 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
@IBOutlet weak var upNextView: UIView!
@IBOutlet weak var timeText: UILabel!
@IBOutlet weak var timeLeftText: UILabel!
@IBOutlet weak var videoContentView: UIView!
@IBOutlet weak var videoControlsView: UIView!
@IBOutlet weak var seekSlider: UISlider!
@ -106,16 +107,26 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
@IBAction func seekSliderValueChanged(_ sender: Any) {
let videoDuration: Double = Double(manifest.runTimeTicks! / Int64(10_000_000))
let secondsScrubbedTo = round(Double(seekSlider.value) * videoDuration)
let scrubRemaining = videoDuration - secondsScrubbedTo
let remainingTime = scrubRemaining
let hours = floor(remainingTime / 3600)
let minutes = (remainingTime.truncatingRemainder(dividingBy: 3600)) / 60
let seconds = (remainingTime.truncatingRemainder(dividingBy: 3600)).truncatingRemainder(dividingBy: 60)
let secondsScrubbedRemaining = videoDuration - secondsScrubbedTo
timeText.text = calculateTimeText(from: secondsScrubbedTo)
timeLeftText.text = calculateTimeText(from: secondsScrubbedRemaining)
}
private func calculateTimeText(from duration: Double) -> String {
let hours = floor(duration / 3600)
let minutes = (duration.truncatingRemainder(dividingBy: 3600)) / 60
let seconds = (duration.truncatingRemainder(dividingBy: 3600)).truncatingRemainder(dividingBy: 60)
let timeText: String
if hours != 0 {
timeText.text = "\(Int(hours)):\(String(Int(floor(minutes))).leftPad(toWidth: 2, withString: "0")):\(String(Int(floor(seconds))).leftPad(toWidth: 2, withString: "0"))"
timeText = "\(Int(hours)):\(String(Int(floor(minutes))).leftPad(toWidth: 2, withString: "0")):\(String(Int(floor(seconds))).leftPad(toWidth: 2, withString: "0"))"
} else {
timeText.text = "\(String(Int(floor(minutes))).leftPad(toWidth: 2, withString: "0")):\(String(Int(floor(seconds))).leftPad(toWidth: 2, withString: "0"))"
timeText = "\(String(Int(floor(minutes))).leftPad(toWidth: 2, withString: "0")):\(String(Int(floor(seconds))).leftPad(toWidth: 2, withString: "0"))"
}
return timeText
}
@IBAction func seekSliderEnd(_ sender: Any) {
@ -215,7 +226,7 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
@IBAction func settingsButtonTapped(_ sender: UIButton) {
optionsVC = VideoPlayerSettingsView()
optionsVC?.delegate = self
optionsVC?.playerDelegate = self
optionsVC?.modalPresentationStyle = .popover
optionsVC?.popoverPresentationController?.sourceView = playerSettingsButton
@ -796,17 +807,11 @@ extension PlayerViewController: GCKGenericChannelDelegate {
}
if isSeeking == false {
let remainingTime = (manifest.runTimeTicks! - Int64(remotePositionTicks))/10_000_000
let hours = remainingTime / 3600
let minutes = (remainingTime % 3600) / 60
let seconds = (remainingTime % 3600) % 60
var timeTextStr = ""
if hours != 0 {
timeTextStr = "\(Int(hours)):\(String(Int((minutes))).leftPad(toWidth: 2, withString: "0")):\(String(Int((seconds))).leftPad(toWidth: 2, withString: "0"))"
} else {
timeTextStr = "\(String(Int((minutes))).leftPad(toWidth: 2, withString: "0")):\(String(Int((seconds))).leftPad(toWidth: 2, withString: "0"))"
}
timeText.text = timeTextStr
let positiveSeconds = Double(remotePositionTicks/10_000_000)
let remainingSeconds = Double((manifest.runTimeTicks! - Int64(remotePositionTicks))/10_000_000)
timeText.text = calculateTimeText(from: positiveSeconds)
timeLeftText.text = calculateTimeText(from: remainingSeconds)
let playbackProgress = Float(remotePositionTicks) / Float(manifest.runTimeTicks!)
seekSlider.setValue(playbackProgress, animated: true)
@ -989,7 +994,8 @@ extension PlayerViewController: VLCMediaPlayerDelegate {
}
}
timeText.text = String(mediaPlayer.remainingTime.stringValue.dropFirst())
timeText.text = mediaPlayer.time.stringValue
timeLeftText.text = String(mediaPlayer.remainingTime.stringValue.dropFirst())
if CACurrentMediaTime() - controlsAppearTime > 5 {
self.smallNextUpView()

View File

@ -8,9 +8,9 @@
import Foundation
import SwiftUI
class VideoPlayerSettingsView: UIViewController {
class VideoPlayerSettingsView: UINavigationController {
private var contentView: UIHostingController<VideoPlayerSettings>!
weak var delegate: PlayerViewController?
weak var playerDelegate: PlayerViewController?
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
.landscape
@ -18,18 +18,13 @@ class VideoPlayerSettingsView: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
contentView = UIHostingController(rootView: VideoPlayerSettings(delegate: self.delegate ?? PlayerViewController()))
self.view.addSubview(contentView.view)
contentView.view.translatesAutoresizingMaskIntoConstraints = false
contentView.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
contentView.view.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
contentView.view.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
contentView.view.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
self.viewControllers = [UIHostingController(rootView: VideoPlayerSettings(delegate: self.playerDelegate ?? PlayerViewController()))]
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.delegate?.settingsPopoverDismissed()
self.playerDelegate?.settingsPopoverDismissed()
}
}
@ -44,44 +39,42 @@ struct VideoPlayerSettings: View {
}
var body: some View {
NavigationView {
Form {
Picker(NSLocalizedString("Closed Captions", comment: ""), selection: $captionTrack) {
ForEach(delegate.subtitleTrackArray, id: \.id) { caption in
Text(caption.name).tag(caption.id)
}
Form {
Picker(NSLocalizedString("Closed Captions", comment: ""), selection: $captionTrack) {
ForEach(delegate.subtitleTrackArray, id: \.id) { caption in
Text(caption.name).tag(caption.id)
}
.onChange(of: captionTrack) { track in
self.delegate.subtitleTrackChanged(newTrackID: track)
}
.onChange(of: captionTrack) { track in
self.delegate.subtitleTrackChanged(newTrackID: track)
}
Picker(NSLocalizedString("Audio Track", comment: ""), selection: $audioTrack) {
ForEach(delegate.audioTrackArray, id: \.id) { caption in
Text(caption.name).tag(caption.id).lineLimit(1)
}
Picker(NSLocalizedString("Audio Track", comment: ""), selection: $audioTrack) {
ForEach(delegate.audioTrackArray, id: \.id) { caption in
Text(caption.name).tag(caption.id).lineLimit(1)
}
}.onChange(of: audioTrack) { track in
self.delegate.audioTrackChanged(newTrackID: track)
}.onChange(of: audioTrack) { track in
self.delegate.audioTrackChanged(newTrackID: track)
}
Picker(NSLocalizedString("Playback Speed", comment: ""), selection: $playbackSpeedSelection) {
ForEach(delegate.playbackSpeeds.indices, id: \.self) { speedIndex in
let speed = delegate.playbackSpeeds[speedIndex]
Text("\(String(speed))x").tag(speedIndex)
}
Picker(NSLocalizedString("Playback Speed", comment: ""), selection: $playbackSpeedSelection) {
ForEach(delegate.playbackSpeeds.indices, id: \.self) { speedIndex in
let speed = delegate.playbackSpeeds[speedIndex]
Text("\(String(speed))x").tag(speedIndex)
}
}
.onChange(of: playbackSpeedSelection, perform: { index in
self.delegate.playbackSpeedChanged(index: index)
})
}.navigationBarTitleDisplayMode(.inline)
.navigationTitle(NSLocalizedString("Audio & Captions", comment: ""))
.toolbar {
ToolbarItemGroup(placement: .navigationBarLeading) {
if UIDevice.current.userInterfaceIdiom == .phone {
Button {
self.delegate.settingsPopoverDismissed()
} label: {
HStack {
Image(systemName: "chevron.left")
Text("Back").font(.callout)
}
}
.onChange(of: playbackSpeedSelection, perform: { index in
self.delegate.playbackSpeedChanged(index: index)
})
}.navigationBarTitleDisplayMode(.inline)
.navigationTitle(NSLocalizedString("Audio & Captions", comment: ""))
.toolbar {
ToolbarItemGroup(placement: .navigationBarLeading) {
if UIDevice.current.userInterfaceIdiom == .phone {
Button {
self.delegate.settingsPopoverDismissed()
} label: {
HStack {
Image(systemName: "chevron.left")
Text("Back").font(.callout)
}
}
}