зеркало из https://github.com/nextcloud/ios.git
subTitle
This commit is contained in:
Родитель
33f513ec59
Коммит
01c63f194f
|
@ -26,4 +26,4 @@ import Foundation
|
|||
// Database Realm
|
||||
//
|
||||
let databaseName = "nextcloud.realm"
|
||||
let databaseSchemaVersion: UInt64 = 292
|
||||
let databaseSchemaVersion: UInt64 = 294
|
||||
|
|
|
@ -28,22 +28,18 @@ import NextcloudKit
|
|||
typealias tableVideo = tableVideoV2
|
||||
class tableVideoV2: Object {
|
||||
|
||||
@objc dynamic var account = ""
|
||||
@objc dynamic var ocId = ""
|
||||
@objc dynamic var position: Float = 0
|
||||
@objc dynamic var width: Int = 0
|
||||
@objc dynamic var height: Int = 0
|
||||
@objc dynamic var length: Int = 0
|
||||
@objc dynamic var codecNameVideo: String?
|
||||
@objc dynamic var codecNameAudio: String?
|
||||
@objc dynamic var codecAudioChannelLayout: String?
|
||||
@objc dynamic var codecAudioLanguage: String?
|
||||
@objc dynamic var codecMaxCompatibility: Bool = false
|
||||
@objc dynamic var codecQuality: String?
|
||||
|
||||
override static func primaryKey() -> String {
|
||||
return "ocId"
|
||||
}
|
||||
@Persisted var account = ""
|
||||
@Persisted(primaryKey: true) var ocId = ""
|
||||
@Persisted var position: Float?
|
||||
@Persisted var width: Int?
|
||||
@Persisted var height: Int?
|
||||
@Persisted var length: Int?
|
||||
@Persisted var codecNameVideo: String?
|
||||
@Persisted var codecNameAudio: String?
|
||||
@Persisted var codecAudioChannelLayout: String?
|
||||
@Persisted var codecAudioLanguage: String?
|
||||
@Persisted var codecMaxCompatibility: Bool = false
|
||||
@Persisted var codecQuality: String?
|
||||
}
|
||||
|
||||
extension NCManageDatabase {
|
||||
|
@ -143,19 +139,6 @@ extension NCManageDatabase {
|
|||
return tableVideo.init(value: result)
|
||||
}
|
||||
|
||||
func getVideoPosition(metadata: tableMetadata) -> Float? {
|
||||
|
||||
if metadata.livePhoto { return nil }
|
||||
let realm = try! Realm()
|
||||
|
||||
guard let result = realm.objects(tableVideo.self).filter("account == %@ AND ocId == %@", metadata.account, metadata.ocId).first else {
|
||||
return nil
|
||||
}
|
||||
|
||||
if result.position == 0 { return nil }
|
||||
return result.position
|
||||
}
|
||||
|
||||
func deleteVideo(metadata: tableMetadata) {
|
||||
|
||||
let realm = try! Realm()
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "subtitles-outline.svg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"preserves-vector-representation" : true
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M20,4A2,2 0 0,1 22,6V18A2,2 0 0,1 20,20H4A2,2 0 0,1 2,18V6A2,2 0 0,1 4,4H20M20,18V6H4V18H20M6,10H8V12H6V10M6,14H14V16H6V14M16,14H18V16H16V14M10,10H18V12H10V10Z" /></svg>
|
До Ширина: | Высота: | Размер: 454 B |
|
@ -69,7 +69,7 @@ class NCPlayer: NSObject {
|
|||
func openAVPlayer(url: URL) {
|
||||
|
||||
let userAgent = CCUtility.getUserAgent()!
|
||||
var position: Float = 0
|
||||
var positionSliderToolBar: Float = 0
|
||||
|
||||
self.url = url
|
||||
self.singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didSingleTapWith(gestureRecognizer:)))
|
||||
|
@ -82,9 +82,9 @@ class NCPlayer: NSObject {
|
|||
// player?.media?.addOption("--network-caching=500")
|
||||
player?.media?.addOption(":http-user-agent=\(userAgent)")
|
||||
|
||||
if let result = NCManageDatabase.shared.getVideoPosition(metadata: metadata) {
|
||||
position = result
|
||||
player?.position = position
|
||||
if let result = NCManageDatabase.shared.getVideo(metadata: metadata), let position = result.position {
|
||||
positionSliderToolBar = position
|
||||
player?.position = positionSliderToolBar
|
||||
}
|
||||
|
||||
player?.drawable = imageVideoContainer
|
||||
|
@ -93,7 +93,7 @@ class NCPlayer: NSObject {
|
|||
view.addGestureRecognizer(singleTapGestureRecognizer)
|
||||
}
|
||||
|
||||
playerToolBar?.setBarPlayer(ncplayer: self, position: position, metadata: metadata, viewerMediaPage: viewerMediaPage)
|
||||
playerToolBar?.setBarPlayer(ncplayer: self, position: positionSliderToolBar, metadata: metadata, viewerMediaPage: viewerMediaPage)
|
||||
|
||||
if let media = player?.media {
|
||||
thumbnailer = VLCMediaThumbnailer(media: media, andDelegate: self)
|
||||
|
@ -134,7 +134,7 @@ class NCPlayer: NSObject {
|
|||
player?.play()
|
||||
playerToolBar?.playButtonPause()
|
||||
|
||||
if let position = NCManageDatabase.shared.getVideoPosition(metadata: metadata) {
|
||||
if let result = NCManageDatabase.shared.getVideo(metadata: metadata), let position = result.position {
|
||||
player?.position = position
|
||||
playerToolBar?.playbackSliderEvent = .moved
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import UIKit
|
|||
import AVKit
|
||||
import MediaPlayer
|
||||
import MobileVLCKit
|
||||
import FloatingPanel
|
||||
|
||||
class NCPlayerToolBar: UIView {
|
||||
|
||||
|
@ -35,6 +36,7 @@ class NCPlayerToolBar: UIView {
|
|||
@IBOutlet weak var playerToolBarView: UIView!
|
||||
@IBOutlet weak var muteButton: UIButton!
|
||||
@IBOutlet weak var playButton: UIButton!
|
||||
@IBOutlet weak var subtitleButton: UIButton!
|
||||
@IBOutlet weak var forwardButton: UIButton!
|
||||
@IBOutlet weak var backButton: UIButton!
|
||||
@IBOutlet weak var playbackSlider: UISlider!
|
||||
|
@ -50,7 +52,8 @@ class NCPlayerToolBar: UIView {
|
|||
|
||||
private var ncplayer: NCPlayer?
|
||||
private var metadata: tableMetadata?
|
||||
private var wasInPlay: Bool = false
|
||||
|
||||
private var subTitleIndex: Int32?
|
||||
|
||||
private weak var viewerMediaPage: NCViewerMediaPage?
|
||||
|
||||
|
@ -88,6 +91,8 @@ class NCPlayerToolBar: UIView {
|
|||
|
||||
playButton.setImage(NCUtility.shared.loadImage(named: "play.fill", color: .white, symbolConfiguration: UIImage.SymbolConfiguration(pointSize: 30)), for: .normal)
|
||||
|
||||
subtitleButton.setImage(NCUtility.shared.loadImage(named: "captions.bubble", color: .white), for: .normal)
|
||||
|
||||
backButton.setImage(NCUtility.shared.loadImage(named: "gobackward.10", color: .white), for: .normal)
|
||||
|
||||
forwardButton.setImage(NCUtility.shared.loadImage(named: "goforward.10", color: .white), for: .normal)
|
||||
|
@ -250,6 +255,19 @@ class NCPlayerToolBar: UIView {
|
|||
self.viewerMediaPage?.startTimerAutoHide()
|
||||
}
|
||||
|
||||
@IBAction func tapSubTitle(_ sender: Any) {
|
||||
|
||||
guard let player = ncplayer?.player else { return }
|
||||
|
||||
let spuTracks = player.videoSubTitlesNames
|
||||
let spuTrackIndexes = player.videoSubTitlesIndexes
|
||||
let count = spuTracks.count
|
||||
|
||||
if count > 1 {
|
||||
toggleMenuSubTitle(spuTracks: spuTracks, spuTrackIndexes: spuTrackIndexes)
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func tapForward(_ sender: Any) {
|
||||
|
||||
guard let ncplayer = ncplayer else { return }
|
||||
|
@ -268,3 +286,37 @@ class NCPlayerToolBar: UIView {
|
|||
self.viewerMediaPage?.startTimerAutoHide()
|
||||
}
|
||||
}
|
||||
|
||||
extension NCPlayerToolBar {
|
||||
|
||||
func toggleMenuSubTitle(spuTracks: [Any], spuTrackIndexes: [Any]) {
|
||||
|
||||
var actions = [NCMenuAction]()
|
||||
let tableVideo = NCManageDatabase.shared.getVideo(metadata: metadata)
|
||||
|
||||
if self.subTitleIndex == nil, let idx = ncplayer?.player?.currentVideoSubTitleIndex {
|
||||
self.subTitleIndex = idx
|
||||
}
|
||||
|
||||
for index in 0...spuTracks.count - 1 {
|
||||
|
||||
guard let title = spuTracks[index] as? String, let idx = spuTrackIndexes[index] as? Int32 else { return }
|
||||
|
||||
actions.append(
|
||||
NCMenuAction(
|
||||
title: title,
|
||||
icon: UIImage(),
|
||||
onTitle: title,
|
||||
onIcon: UIImage(),
|
||||
selected: (self.subTitleIndex ?? -9999) == idx,
|
||||
on: (self.subTitleIndex ?? -9999) == idx,
|
||||
action: { _ in
|
||||
self.ncplayer?.player?.currentVideoSubTitleIndex = idx
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
viewerMediaPage?.presentMenu(with: actions)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,23 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="XfW-XC-eMf" userLabel="Player Top Tool Bar">
|
||||
<rect key="frame" x="369" y="58" width="35" height="35"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="XfW-XC-eMf" userLabel="Player Top Tool Bar">
|
||||
<rect key="frame" x="329" y="58" width="75" height="35"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fml-c2-FMY">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qqZ-QN-TsW">
|
||||
<rect key="frame" x="5" y="5" width="25" height="25"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="25" id="S3q-Dj-i67"/>
|
||||
<constraint firstAttribute="width" constant="25" id="rg2-EW-KJX"/>
|
||||
</constraints>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||
<state key="normal" image="captions.bubble" catalog="system"/>
|
||||
<connections>
|
||||
<action selector="tapSubTitle:" destination="iN0-l3-epB" eventType="touchUpInside" id="ooC-tL-TBX"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Fml-c2-FMY">
|
||||
<rect key="frame" x="45" y="5" width="25" height="25"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="25" id="S8g-UR-4zh"/>
|
||||
<constraint firstAttribute="height" constant="25" id="zjo-O1-SI2"/>
|
||||
|
@ -138,12 +150,14 @@
|
|||
<outlet property="playbackSlider" destination="MY0-FC-j88" id="bVe-Kc-80k"/>
|
||||
<outlet property="playerToolBarView" destination="85m-50-8yp" id="eZK-p1-v65"/>
|
||||
<outlet property="playerTopToolBarView" destination="XfW-XC-eMf" id="Qdp-IW-YhT"/>
|
||||
<outlet property="subtitleButton" destination="qqZ-QN-TsW" id="XCP-hb-eZB"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="137.68115942028987" y="152.67857142857142"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="audioOn" width="28" height="28"/>
|
||||
<image name="captions.bubble" catalog="system" width="128" height="110"/>
|
||||
<image name="gobackward.10" catalog="system" width="119" height="128"/>
|
||||
<image name="goforward.10" catalog="system" width="119" height="128"/>
|
||||
<image name="play.fill" catalog="system" width="117" height="128"/>
|
||||
|
|
|
@ -69,7 +69,7 @@ class NCViewerMediaPage: UIViewController {
|
|||
var timerAutoHideSeconds: Double {
|
||||
get {
|
||||
if NCUtility.shared.isSimulator() {
|
||||
return 5
|
||||
return 20
|
||||
} else {
|
||||
return 4
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче