WIP
This commit is contained in:
@@ -9,12 +9,12 @@
|
||||
/* Begin PBXBuildFile section */
|
||||
1C31C8842A53AE3E00350540 /* short_beep.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 1C31C8822A53AE3E00350540 /* short_beep.m4a */; };
|
||||
1C31C8852A53AE3E00350540 /* long_beep.m4a in Resources */ = {isa = PBXBuildFile; fileRef = 1C31C8832A53AE3E00350540 /* long_beep.m4a */; };
|
||||
1C31C8872A55B2CC00350540 /* PlayerUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C31C8862A55B2CC00350540 /* PlayerUIView.swift */; };
|
||||
1C485C832A489B9C00A6F896 /* CompletedWorkouts.json in Resources */ = {isa = PBXBuildFile; fileRef = 1C485C822A489B9C00A6F896 /* CompletedWorkouts.json */; };
|
||||
1C485C872A4915C400A6F896 /* CreateWorkoutItemPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C485C862A4915C400A6F896 /* CreateWorkoutItemPickerView.swift */; };
|
||||
1C485C8A2A492BB400A6F896 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C485C892A492BB400A6F896 /* LoginView.swift */; };
|
||||
1C485C8C2A49D65600A6F896 /* WorkoutHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C485C8B2A49D65600A6F896 /* WorkoutHistoryView.swift */; };
|
||||
1C485C8D2A49D95700A6F896 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A822A42347D0042FFBD /* Extensions.swift */; };
|
||||
1C6D0A372A4BE9A500D98B06 /* VideoPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C6D0A362A4BE9A500D98B06 /* VideoPlayerView.swift */; };
|
||||
1CAF4D8A2A5132F900B00E50 /* PlannedWorkout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CAF4D892A5132F900B00E50 /* PlannedWorkout.swift */; };
|
||||
1CAF4D8C2A51339200B00E50 /* PlannedWorkouts.json in Resources */ = {isa = PBXBuildFile; fileRef = 1CAF4D8B2A51339200B00E50 /* PlannedWorkouts.json */; };
|
||||
1CAF4D952A52180600B00E50 /* PlanWorkoutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CAF4D942A52180600B00E50 /* PlanWorkoutView.swift */; };
|
||||
@@ -106,11 +106,11 @@
|
||||
/* Begin PBXFileReference section */
|
||||
1C31C8822A53AE3E00350540 /* short_beep.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = short_beep.m4a; sourceTree = "<group>"; };
|
||||
1C31C8832A53AE3E00350540 /* long_beep.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = long_beep.m4a; sourceTree = "<group>"; };
|
||||
1C31C8862A55B2CC00350540 /* PlayerUIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerUIView.swift; sourceTree = "<group>"; };
|
||||
1C485C822A489B9C00A6F896 /* CompletedWorkouts.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = CompletedWorkouts.json; sourceTree = "<group>"; };
|
||||
1C485C862A4915C400A6F896 /* CreateWorkoutItemPickerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateWorkoutItemPickerView.swift; sourceTree = "<group>"; };
|
||||
1C485C892A492BB400A6F896 /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; };
|
||||
1C485C8B2A49D65600A6F896 /* WorkoutHistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkoutHistoryView.swift; sourceTree = "<group>"; };
|
||||
1C6D0A362A4BE9A500D98B06 /* VideoPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerView.swift; sourceTree = "<group>"; };
|
||||
1C6D0A3C2A4BEC9700D98B06 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS9.4.sdk/System/Library/Frameworks/AVKit.framework; sourceTree = DEVELOPER_DIR; };
|
||||
1C6D0A3D2A4BEC9700D98B06 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS9.4.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
1C6D0A402A4BECA400D98B06 /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.4.sdk/System/Library/Frameworks/AVKit.framework; sourceTree = DEVELOPER_DIR; };
|
||||
@@ -289,7 +289,7 @@
|
||||
1CF65A3B2A3972CE0042FFBD /* ExternalWorkoutDetailView.swift */,
|
||||
1CF65A2C2A3972840042FFBD /* MainView.swift */,
|
||||
1CAF4D942A52180600B00E50 /* PlanWorkoutView.swift */,
|
||||
1C6D0A362A4BE9A500D98B06 /* VideoPlayerView.swift */,
|
||||
1C31C8862A55B2CC00350540 /* PlayerUIView.swift */,
|
||||
1C485C8B2A49D65600A6F896 /* WorkoutHistoryView.swift */,
|
||||
1CF65A8B2A44B7590042FFBD /* AccountView */,
|
||||
1CF65A8A2A44B74D0042FFBD /* AddExercise */,
|
||||
@@ -529,7 +529,6 @@
|
||||
1CF65A522A3A90A00042FFBD /* PreviewData.swift in Sources */,
|
||||
1CF65A852A43E8060042FFBD /* CompletedWorkout.swift in Sources */,
|
||||
1CF65A6E2A3F60480042FFBD /* CreateViewModels.swift in Sources */,
|
||||
1C6D0A372A4BE9A500D98B06 /* VideoPlayerView.swift in Sources */,
|
||||
1CF65A4C2A39FDA20042FFBD /* WorkoutDetailView.swift in Sources */,
|
||||
1CF65A8E2A44B78B0042FFBD /* CompletedWorkoutView.swift in Sources */,
|
||||
1CF65A432A39FB410042FFBD /* Workout.swift in Sources */,
|
||||
@@ -537,6 +536,7 @@
|
||||
1CF65A592A3BF4B60042FFBD /* Muscle.swift in Sources */,
|
||||
1CAF4D8A2A5132F900B00E50 /* PlannedWorkout.swift in Sources */,
|
||||
1CF65A2B2A3972840042FFBD /* Werkout_ios.xcdatamodeld in Sources */,
|
||||
1C31C8872A55B2CC00350540 /* PlayerUIView.swift in Sources */,
|
||||
1CF65A2D2A3972840042FFBD /* MainView.swift in Sources */,
|
||||
1CF65A7D2A41275D0042FFBD /* Network.swift in Sources */,
|
||||
1C485C8A2A492BB400A6F896 /* LoginView.swift in Sources */,
|
||||
|
||||
@@ -72,7 +72,10 @@ struct AddExerciseView: View {
|
||||
filteredExercises = exercises
|
||||
}
|
||||
.sheet(item: $videoExercise) { exercise in
|
||||
VideoPlayerView(avPlayer: $avPlayer)
|
||||
PlayerView(player: $avPlayer)
|
||||
.onAppear{
|
||||
avPlayer.play()
|
||||
}
|
||||
}
|
||||
.sheet(item: $createWorkoutItemPickerViewModel) { item in
|
||||
CreateWorkoutItemPickerView(viewModel: item, completed: { selectedids in
|
||||
|
||||
@@ -19,8 +19,11 @@ struct ExternalWorkoutDetailView: View {
|
||||
GeometryReader { metrics in
|
||||
VStack {
|
||||
HStack {
|
||||
VideoPlayerView(avPlayer: $avPlayer, showDoneButton: false)
|
||||
PlayerView(player: $avPlayer)
|
||||
.frame(width: metrics.size.width * 0.6, height: metrics.size.height * 0.8)
|
||||
.onAppear{
|
||||
avPlayer.play()
|
||||
}
|
||||
|
||||
ExtExerciseList(workout: workout,
|
||||
currentExerciseIdx: bridgeModule.currentExerciseIdx)
|
||||
@@ -39,17 +42,22 @@ struct ExternalWorkoutDetailView: View {
|
||||
}
|
||||
}
|
||||
.onChange(of: bridgeModule.currentExercise, perform: { newValue in
|
||||
var _url: URL?
|
||||
if showNSFWVideos {
|
||||
if let viddd = newValue?.exercise.nsfwVideoURL,
|
||||
let url = URL(string: BaseURLs.currentBaseURL + viddd) {
|
||||
avPlayer = AVPlayer(url: url)
|
||||
_url = url
|
||||
}
|
||||
} else {
|
||||
if let viddd = newValue?.exercise.videoURL,
|
||||
let url = URL(string: BaseURLs.currentBaseURL + viddd) {
|
||||
avPlayer = AVPlayer(url: url)
|
||||
_url = url
|
||||
}
|
||||
}
|
||||
if let __url = _url {
|
||||
avPlayer = AVPlayer(url: __url)
|
||||
avPlayer.play()
|
||||
}
|
||||
})
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.background(.background)
|
||||
|
||||
82
Werkout_ios/Views/PlayerUIView.swift
Normal file
82
Werkout_ios/Views/PlayerUIView.swift
Normal file
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// PlayerUIView.swift
|
||||
// Werkout_ios
|
||||
//
|
||||
// Created by Trey Tartt on 7/5/23.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import AVKit
|
||||
|
||||
class PlayerUIView: UIView {
|
||||
|
||||
// MARK: Class Property
|
||||
|
||||
let playerLayer = AVPlayerLayer()
|
||||
|
||||
// MARK: Init
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
init(player: AVPlayer) {
|
||||
super.init(frame: .zero)
|
||||
self.playerSetup(player: player)
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
// MARK: Life-Cycle
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
playerLayer.frame = bounds
|
||||
}
|
||||
|
||||
// MARK: Class Methods
|
||||
|
||||
private func playerSetup(player: AVPlayer) {
|
||||
playerLayer.player = player
|
||||
player.actionAtItemEnd = .none
|
||||
layer.addSublayer(playerLayer)
|
||||
|
||||
self.setObserver()
|
||||
}
|
||||
|
||||
func setObserver() {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidReachEnd(notification:)),
|
||||
name: .AVPlayerItemDidPlayToEndTime,
|
||||
object: playerLayer.player?.currentItem)
|
||||
}
|
||||
|
||||
@objc func playerItemDidReachEnd(notification: Notification) {
|
||||
if let playerItem = notification.object as? AVPlayerItem {
|
||||
playerItem.seek(to: .zero, completionHandler: nil)
|
||||
self.playerLayer.player?.play()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PlayerView: UIViewRepresentable {
|
||||
|
||||
@Binding var player: AVPlayer
|
||||
|
||||
func makeUIView(context: Context) -> PlayerUIView {
|
||||
return PlayerUIView(player: player)
|
||||
}
|
||||
|
||||
func updateUIView(_ uiView: PlayerUIView, context: UIViewRepresentableContext<PlayerView>) {
|
||||
uiView.playerLayer.player = player
|
||||
|
||||
//Add player observer.
|
||||
uiView.setObserver()
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
//
|
||||
// VideoPlayerView.swift
|
||||
// Werkout_ios
|
||||
//
|
||||
// Created by Trey Tartt on 6/27/23.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import AVKit
|
||||
import Combine
|
||||
|
||||
struct VideoPlayerView: View {
|
||||
@Environment(\.dismiss) var dismiss
|
||||
@Binding var avPlayer: AVPlayer
|
||||
var showDoneButton = true
|
||||
|
||||
var pub = NotificationCenter.default.publisher(for: .AVPlayerItemDidPlayToEndTime)
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
if self.showDoneButton {
|
||||
Button(action: {
|
||||
dismiss()
|
||||
}, label: {
|
||||
Text("Done")
|
||||
})
|
||||
.padding()
|
||||
.frame(maxWidth: .infinity)
|
||||
.background(Color(uiColor: UIColor(red: 0.11, green: 0.11, blue: 0.12, alpha: 1)))
|
||||
}
|
||||
|
||||
VideoPlayer(player: avPlayer)
|
||||
.onAppear{
|
||||
_ = try? AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: .default, options: .mixWithOthers)
|
||||
|
||||
avPlayer.play()
|
||||
}
|
||||
}
|
||||
.background(.black)
|
||||
.onReceive(pub) { (output) in
|
||||
avPlayer.pause()
|
||||
avPlayer.seek(to: .zero)
|
||||
_ = try? AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: .default, options: .mixWithOthers)
|
||||
|
||||
avPlayer.play()
|
||||
}
|
||||
.onChange(of: avPlayer, perform: { newValue in
|
||||
avPlayer.play()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//struct VideoPlayerView_Previews: PreviewProvider {
|
||||
// static let exercise = PreviewData.parseExercises().first!
|
||||
//
|
||||
// static var previews: some View {
|
||||
// VideoPlayerView(url: Bundle.main.url(forResource: "Straight_Leg_Sit_Up", withExtension: "mp4")!)
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -40,8 +40,11 @@ struct WorkoutDetailView: View {
|
||||
.padding()
|
||||
|
||||
GeometryReader { metrics in
|
||||
WorkoutDetailVideoPlayerView(avPlayer: $avPlayer)
|
||||
PlayerView(player: $avPlayer)
|
||||
.frame(width: metrics.size.width * 1, height: metrics.size.height * 1)
|
||||
.onAppear{
|
||||
avPlayer.play()
|
||||
}
|
||||
}
|
||||
}
|
||||
InfoView(workout: workout)
|
||||
@@ -75,17 +78,22 @@ struct WorkoutDetailView: View {
|
||||
}
|
||||
}
|
||||
.onChange(of: bridgeModule.currentExercise, perform: { newValue in
|
||||
var _url: URL?
|
||||
if showNSFWVideos {
|
||||
if let viddd = newValue?.exercise.nsfwVideoURL,
|
||||
let url = URL(string: BaseURLs.currentBaseURL + viddd) {
|
||||
avPlayer = AVPlayer(url: url)
|
||||
_url = url
|
||||
}
|
||||
} else {
|
||||
if let viddd = newValue?.exercise.videoURL,
|
||||
let url = URL(string: BaseURLs.currentBaseURL + viddd) {
|
||||
avPlayer = AVPlayer(url: url)
|
||||
_url = url
|
||||
}
|
||||
}
|
||||
if let __url = _url {
|
||||
avPlayer = AVPlayer(url: __url)
|
||||
avPlayer.play()
|
||||
}
|
||||
})
|
||||
.onAppear{
|
||||
bridgeModule.completedWorkout = {
|
||||
@@ -118,15 +126,6 @@ struct WorkoutDetailView: View {
|
||||
}
|
||||
}
|
||||
|
||||
struct WorkoutDetailVideoPlayerView: View {
|
||||
@ObservedObject var bridgeModule = BridgeModule.shared
|
||||
@Binding var avPlayer: AVPlayer
|
||||
|
||||
var body: some View {
|
||||
VideoPlayerView(avPlayer: $avPlayer, showDoneButton: false)
|
||||
}
|
||||
}
|
||||
|
||||
struct InfoView: View {
|
||||
@ObservedObject var bridgeModule = BridgeModule.shared
|
||||
var workout: Workout
|
||||
@@ -306,7 +305,10 @@ struct ExerciseListView: View {
|
||||
}
|
||||
}
|
||||
.sheet(item: $videoExercise) { exercise in
|
||||
VideoPlayerView(avPlayer: $avPlayer)
|
||||
PlayerView(player: $avPlayer)
|
||||
.onAppear{
|
||||
avPlayer.play()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user