|
|
|
@ -6,12 +6,14 @@ |
|
|
|
import Foundation |
|
|
|
import SwiftUI |
|
|
|
import AVKit |
|
|
|
import CoreMotion |
|
|
|
|
|
|
|
struct SVideoPlayer: View, EditItemDelegate { |
|
|
|
// url: URL(string: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8")! |
|
|
|
var player = AVQueuePlayer(items: [AVPlayerItem]()) |
|
|
|
var playerLooper : AVPlayerLooper |
|
|
|
var completionHandler: ((Bool) -> Void)? |
|
|
|
let motionManager = CMMotionManager() |
|
|
|
|
|
|
|
@ObservedObject |
|
|
|
var model: SVideoModel |
|
|
|
@ -22,9 +24,13 @@ struct SVideoPlayer: View, EditItemDelegate { |
|
|
|
@State var savetext = "save" |
|
|
|
@State var confirmationShown = false |
|
|
|
@State var seekSmoothly = false |
|
|
|
@State var upsidedown = false |
|
|
|
@State var tilt = false |
|
|
|
@State var smoothTime = -1.0 |
|
|
|
@State var smoothSeekTime = -1.0 |
|
|
|
@State var timeCounter = 0 |
|
|
|
@State var xoffs = 0.0 |
|
|
|
@State var rotazero = -1000.0 |
|
|
|
|
|
|
|
@State var orientation = UIDevice.current.orientation |
|
|
|
|
|
|
|
@ -74,6 +80,22 @@ struct SVideoPlayer: View, EditItemDelegate { |
|
|
|
Text("zoom") |
|
|
|
}) |
|
|
|
.foregroundColor(model.zoomed ? Color.yellow : Color.blue).buttonStyle(BorderlessButtonStyle()) |
|
|
|
Button(action: { |
|
|
|
upsidedown.toggle() |
|
|
|
}, label: { |
|
|
|
Text("flip") |
|
|
|
}).foregroundColor(upsidedown ? Color.yellow : Color.blue).buttonStyle(BorderlessButtonStyle()) |
|
|
|
Button(action: { |
|
|
|
tilt.toggle() |
|
|
|
if tilt { |
|
|
|
motionManager.startDeviceMotionUpdates(using: .xMagneticNorthZVertical) |
|
|
|
} |
|
|
|
else { |
|
|
|
motionManager.stopDeviceMotionUpdates() |
|
|
|
} |
|
|
|
}, label: { |
|
|
|
Text("tilt") |
|
|
|
}).foregroundColor(tilt ? Color.yellow : Color.blue).buttonStyle(BorderlessButtonStyle()) |
|
|
|
Button(action: { |
|
|
|
model.favorite.toggle() |
|
|
|
}, label: { |
|
|
|
@ -149,7 +171,8 @@ struct SVideoPlayer: View, EditItemDelegate { |
|
|
|
let v = VideoPlayerView(model: model, |
|
|
|
player: player) |
|
|
|
.scaleEffect(model.scale) |
|
|
|
.offset(model.dragOffset) |
|
|
|
.rotation3DEffect(.degrees(upsidedown ? 180 : 0), axis: (x: 1, y: 0, z: 0)) |
|
|
|
.offset(model.dragOffset).offset(x: xoffs, y:0) |
|
|
|
.gesture( |
|
|
|
DragGesture() |
|
|
|
.onChanged { gesture in |
|
|
|
@ -195,7 +218,7 @@ struct SVideoPlayer: View, EditItemDelegate { |
|
|
|
|
|
|
|
} |
|
|
|
.onAppear() { |
|
|
|
model.observer = player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 0.1, preferredTimescale: 600), queue: nil) { time in |
|
|
|
model.observer = player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 0.02, preferredTimescale: 600), queue: nil) { time in |
|
|
|
if timeCounter >= 1 { |
|
|
|
timeCounter -= 1 |
|
|
|
} |
|
|
|
@ -204,7 +227,36 @@ struct SVideoPlayer: View, EditItemDelegate { |
|
|
|
seekTime(model.currentSnapshot.time) |
|
|
|
} |
|
|
|
} |
|
|
|
if tilt { |
|
|
|
if let data = motionManager.deviceMotion { |
|
|
|
var rotation = atan2(data.gravity.x, |
|
|
|
data.gravity.y) - .pi |
|
|
|
|
|
|
|
if rotation < (-1 * .pi) { |
|
|
|
rotation += .pi + .pi |
|
|
|
} |
|
|
|
rotation *= 100.0 |
|
|
|
if rotazero == -1000 { |
|
|
|
rotazero = rotation |
|
|
|
} |
|
|
|
|
|
|
|
rotation -= rotazero |
|
|
|
|
|
|
|
// let roll = accelerometerData.attitude.yaw |
|
|
|
if rotation > 30 { |
|
|
|
xoffs += 3; |
|
|
|
// print(xoffs) |
|
|
|
} |
|
|
|
if rotation < -30 { |
|
|
|
xoffs -= 3; |
|
|
|
// print(xoffs) |
|
|
|
} |
|
|
|
// print(Int(rotation * 100.0) ) |
|
|
|
}} |
|
|
|
else { |
|
|
|
xoffs = 0.0 |
|
|
|
rotazero = -1000 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
player.automaticallyWaitsToMinimizeStalling = false |
|
|
|
|