mirror of
https://github.com/cranci1/Sora.git
synced 2026-01-11 20:10:24 +00:00
added close button
This commit is contained in:
parent
5ccbbf1c1b
commit
71d243dba5
5 changed files with 187 additions and 170 deletions
Binary file not shown.
|
|
@ -4,7 +4,7 @@
|
|||
//
|
||||
// Created by Pratik on 14/01/23.
|
||||
//
|
||||
// Thanks to pratikg29 for this code inside his open source project "https://github.com/pratikg29/Custom-Slider-Control?ref=iosexample.com"
|
||||
// Thanks to pratikg29 for this code inside his open source project "https://github.com/pratikg29/Custom-Slider-Control?ref=iosexample.com"
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@
|
|||
//
|
||||
// Created by Pratik on 08/01/23.
|
||||
//
|
||||
// Thanks to pratikg29 for this code inside his open source project "https://github.com/pratikg29/Custom-Slider-Control?ref=iosexample.com"
|
||||
// Thanks to pratikg29 for this code inside his open source project "https://github.com/pratikg29/Custom-Slider-Control?ref=iosexample.com"
|
||||
// I did edit just a little bit the code for my liking
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ struct CustomMediaPlayer: View {
|
|||
@State private var duration: Double = 0.0
|
||||
@State private var showControls = false
|
||||
@State private var inactivityTimer: Timer?
|
||||
@Environment(\.presentationMode) var presentationMode
|
||||
|
||||
init(urlString: String) {
|
||||
guard let url = URL(string: urlString) else {
|
||||
|
|
@ -50,176 +51,194 @@ struct CustomMediaPlayer: View {
|
|||
}
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
ZStack {
|
||||
CustomVideoPlayer(player: player)
|
||||
.onAppear {
|
||||
player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1, preferredTimescale: 600), queue: .main) { time in
|
||||
currentTime = time.seconds
|
||||
if let itemDuration = player.currentItem?.duration.seconds, itemDuration.isFinite && !itemDuration.isNaN {
|
||||
duration = itemDuration
|
||||
ZStack {
|
||||
VStack {
|
||||
ZStack {
|
||||
CustomVideoPlayer(player: player)
|
||||
.onAppear {
|
||||
player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1, preferredTimescale: 600), queue: .main) { time in
|
||||
currentTime = time.seconds
|
||||
if let itemDuration = player.currentItem?.duration.seconds, itemDuration.isFinite && !itemDuration.isNaN {
|
||||
duration = itemDuration
|
||||
}
|
||||
}
|
||||
startUpdatingCurrentTime()
|
||||
}
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
.overlay(
|
||||
Group {
|
||||
if showControls {
|
||||
Color.black.opacity(0.5)
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
HStack(spacing: 20) {
|
||||
Button(action: {
|
||||
currentTime = max(currentTime - 10, 0)
|
||||
player.seek(to: CMTime(seconds: currentTime, preferredTimescale: 600))
|
||||
}) {
|
||||
Image(systemName: "gobackward.10")
|
||||
}
|
||||
.foregroundColor(.white)
|
||||
.font(.system(size: 25))
|
||||
.contentShape(Rectangle())
|
||||
.frame(width: 60, height: 60)
|
||||
|
||||
Button(action: {
|
||||
if isPlaying {
|
||||
player.pause()
|
||||
} else {
|
||||
player.play()
|
||||
}
|
||||
isPlaying.toggle()
|
||||
}) {
|
||||
Image(systemName: isPlaying ? "pause.fill" : "play.fill")
|
||||
}
|
||||
.foregroundColor(.white)
|
||||
.font(.system(size: 45))
|
||||
.contentShape(Rectangle())
|
||||
.frame(width: 80, height: 80)
|
||||
|
||||
Button(action: {
|
||||
currentTime = min(currentTime + 10, duration)
|
||||
player.seek(to: CMTime(seconds: currentTime, preferredTimescale: 600))
|
||||
}) {
|
||||
Image(systemName: "goforward.10")
|
||||
}
|
||||
.foregroundColor(.white)
|
||||
.font(.system(size: 25))
|
||||
.contentShape(Rectangle())
|
||||
.frame(width: 60, height: 60)
|
||||
}
|
||||
}
|
||||
},
|
||||
alignment: .center
|
||||
)
|
||||
.onTapGesture {
|
||||
showControls.toggle()
|
||||
}
|
||||
|
||||
VStack {
|
||||
Spacer()
|
||||
if showControls {
|
||||
VStack {
|
||||
Spacer()
|
||||
HStack {
|
||||
Spacer()
|
||||
Menu {
|
||||
Menu("Playback Speed") {
|
||||
Button(action: {
|
||||
player.rate = 0.25
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("0.25", systemImage: "tortoise")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 0.5
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("0.5", systemImage: "tortoise.fill")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 0.75
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("0.75", systemImage: "hare")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 1.0
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("1.0", systemImage: "hare.fill")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 1.25
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("1.25", systemImage: "speedometer")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 1.5
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("1.5", systemImage: "speedometer")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 1.75
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("1.75", systemImage: "speedometer")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 2.0
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("2.0", systemImage: "speedometer")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "ellipsis.circle")
|
||||
.foregroundColor(.white)
|
||||
.font(.system(size: 15))
|
||||
}
|
||||
}
|
||||
.padding(.trailing, 10)
|
||||
|
||||
MusicProgressSlider(
|
||||
value: $currentTime,
|
||||
inRange: 0...duration,
|
||||
activeFillColor: .white,
|
||||
fillColor: .white.opacity(0.5),
|
||||
emptyColor: .white.opacity(0.3),
|
||||
height: 28,
|
||||
onEditingChanged: { editing in
|
||||
if !editing {
|
||||
player.seek(to: CMTime(seconds: currentTime, preferredTimescale: 600))
|
||||
}
|
||||
}
|
||||
)
|
||||
.frame(height: 45)
|
||||
.padding(.bottom, 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
startUpdatingCurrentTime()
|
||||
}
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
.overlay(
|
||||
Group {
|
||||
if showControls {
|
||||
Color.black.opacity(0.5)
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
HStack(spacing: 20) {
|
||||
Button(action: {
|
||||
currentTime = max(currentTime - 10, 0)
|
||||
player.seek(to: CMTime(seconds: currentTime, preferredTimescale: 600))
|
||||
}) {
|
||||
Image(systemName: "gobackward.10")
|
||||
}
|
||||
.foregroundColor(.white)
|
||||
.font(.system(size: 25))
|
||||
.contentShape(Rectangle())
|
||||
.frame(width: 60, height: 60)
|
||||
|
||||
Button(action: {
|
||||
if isPlaying {
|
||||
player.pause()
|
||||
} else {
|
||||
player.play()
|
||||
}
|
||||
isPlaying.toggle()
|
||||
}) {
|
||||
Image(systemName: isPlaying ? "pause.fill" : "play.fill")
|
||||
}
|
||||
.foregroundColor(.white)
|
||||
.font(.system(size: 45))
|
||||
.contentShape(Rectangle())
|
||||
.frame(width: 80, height: 80)
|
||||
|
||||
Button(action: {
|
||||
currentTime = min(currentTime + 10, duration)
|
||||
player.seek(to: CMTime(seconds: currentTime, preferredTimescale: 600))
|
||||
}) {
|
||||
Image(systemName: "goforward.10")
|
||||
}
|
||||
.foregroundColor(.white)
|
||||
.font(.system(size: 25))
|
||||
.contentShape(Rectangle())
|
||||
.frame(width: 60, height: 60)
|
||||
}
|
||||
}
|
||||
},
|
||||
alignment: .center
|
||||
)
|
||||
.onTapGesture {
|
||||
showControls.toggle()
|
||||
.onDisappear {
|
||||
player.pause()
|
||||
inactivityTimer?.invalidate()
|
||||
}
|
||||
|
||||
VStack {
|
||||
Spacer()
|
||||
if showControls {
|
||||
VStack {
|
||||
Spacer()
|
||||
HStack {
|
||||
Spacer()
|
||||
Menu {
|
||||
Menu("Playback Speed") {
|
||||
Button(action: {
|
||||
player.rate = 0.25
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("0.25", systemImage: "tortoise")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 0.5
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("0.5", systemImage: "tortoise.fill")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 0.75
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("0.75", systemImage: "hare")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 1.0
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("1.0", systemImage: "hare.fill")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 1.25
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("1.25", systemImage: "speedometer")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 1.5
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("1.5", systemImage: "speedometer")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 1.75
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("1.75", systemImage: "speedometer")
|
||||
}
|
||||
Button(action: {
|
||||
player.rate = 2.0
|
||||
if player.timeControlStatus != .playing {
|
||||
player.pause()
|
||||
}
|
||||
}) {
|
||||
Label("2.0", systemImage: "speedometer")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "ellipsis.circle")
|
||||
.foregroundColor(.white)
|
||||
.font(.system(size: 15))
|
||||
}
|
||||
}
|
||||
.padding(.trailing, 10)
|
||||
|
||||
MusicProgressSlider(
|
||||
value: $currentTime,
|
||||
inRange: 0...duration,
|
||||
activeFillColor: .white,
|
||||
fillColor: .white.opacity(0.5),
|
||||
emptyColor: .white.opacity(0.3),
|
||||
height: 28,
|
||||
onEditingChanged: { editing in
|
||||
if !editing {
|
||||
player.seek(to: CMTime(seconds: currentTime, preferredTimescale: 600))
|
||||
}
|
||||
}
|
||||
)
|
||||
.frame(height: 45)
|
||||
.padding(.bottom, 10)
|
||||
}
|
||||
}
|
||||
VStack {
|
||||
if showControls {
|
||||
HStack {
|
||||
Button(action: {
|
||||
presentationMode.wrappedValue.dismiss()
|
||||
}) {
|
||||
Image(systemName: "xmark")
|
||||
.foregroundColor(.white)
|
||||
.font(.system(size: 20))
|
||||
}
|
||||
.padding()
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
startUpdatingCurrentTime()
|
||||
}
|
||||
.onDisappear {
|
||||
player.pause()
|
||||
inactivityTimer?.invalidate()
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -230,4 +249,4 @@ struct CustomMediaPlayer: View {
|
|||
currentTime = player.currentTime().seconds
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,10 +35,7 @@ struct SettingsView: View {
|
|||
Text("Minor Interface Settings")
|
||||
}
|
||||
NavigationLink(destination: SettingsPlayerView()) {
|
||||
HStack {
|
||||
Image(systemName: "play.fill")
|
||||
Text("Player")
|
||||
}
|
||||
Text("Player")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue