I use AVPlayer for streaming mp3 file from the internet and i want to give the user a option to delay the audio the seconds he want.
Is there any tip of how to do it or what should i start looking for?
I am trying whit something like this:
player?.pause()
DispatchQueue.main.asyncAfter(deadline: .now() 5, execute: {
self.player.play()
})
CodePudding user response:
You can make 5 seconds delay with following code:
if let currentTime:CMTime = self.avPlayer.currentItem?.currentTime() {
let fiveSeconds = CMTime.init(seconds: 5, preferredTimescale: 100)
let fiveSecondsBackTime = currentTime - fiveSeconds
self.avPlayer.seek(to: fiveSecondsBackTime)
}
CodePudding user response:
In my SwiftUI project it is working exactly as you mentioned above. I implemented a looping video player (see below) with a 10 seconds delay (just for testing) and it works well. Of course you would have to add a var with the user input for the desired delay duration time. Do you face any problems?
//
// PlayerView.swift
//
// Created by Sebastian on 11.08.22.
//
import Foundation
import SwiftUI
import AVKit
import AVFoundation
import UIKit
struct PlayerView: UIViewRepresentable {
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PlayerView>) {
}
func makeUIView(context: Context) -> UIView {
return LoopingPlayerUIView(frame: .zero)
}
}
class LoopingPlayerUIView: UIView {
private let playerLayer = AVPlayerLayer()
private var playerLooper: AVPlayerLooper?
let videos = ["video_3", "video_10", "video_8", "video_9"]
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(frame: CGRect) {
super.init(frame: frame)
// Load the resource -> h
let fileUrl = Bundle.main.url(forResource: videos.randomElement(), withExtension: "mov")!
let asset = AVAsset(url: fileUrl)
let item = AVPlayerItem(asset: asset)
// Setup the player
let player = AVQueuePlayer()
player.volume = 0
playerLayer.player = player
playerLayer.videoGravity = .resizeAspectFill
layer.addSublayer(playerLayer)
// Create a new player looper with the queue player and template item
playerLooper = AVPlayerLooper(player: player, templateItem: item)
// Start the movie
DispatchQueue.main.asyncAfter(deadline: .now() 10) {
player.play()
}
}
override func layoutSubviews() {
super.layoutSubviews()
playerLayer.frame = bounds
}
}
All I do is to use the video player in the view.
//
// ContentView.swift
// SwiftTest
//
// Created by Sebastian on 11.08.22.
//
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack() {
GeometryReader{ geo -> AnyView in
return AnyView(
PlayerView()
.aspectRatio(contentMode: .fill)
.frame(width: geo.size.width, height: geo.size.height 100)
.edgesIgnoringSafeArea(.all)
.overlay(Color.black.opacity(0.2))
.blur(radius: 1)
.edgesIgnoringSafeArea(.all)
)
}
}
}
}
Best, Sebastian