I’m utilizing TvOSSlider in my television app to create a seek-bar and play audio monitor with AVAudioPlayer. My downside is that it’s stuttering each time i replace the seekbar/slider by means of code. So at present it’s set to stutter each 1.0seconds. UISlider is unavailable in tvOS that’s the reason i’m utilizing this completely different library.
func playAudio(url: URL, completion: (() -> Void)? = nil) {
stopAudio()
do {
audioPlayer = strive AVAudioPlayer(contentsOf: url as URL)
audioPlayer?.delegate = self
audioPlayer?.prepareToPlay()
audioPlayer?.play()
isPaused = false
// Begin the playback timer to replace the search bar
DispatchQueue.important.async { [self] in
// That is the place timer is about and replace Slider methodology is known as. I attempted to set it from 0.1 sec to five sec
playbackTimer = Timer.scheduledTimer(timeInterval: 1.0, goal: self, selector: #selector(updateSlider), userInfo: nil, repeats: true)
}
completion?()
} catch let error as NSError {
print("Error initializing AVAudioPlayer: (error.localizedDescription)")
completion?()
}
}
// Replace the slider worth based mostly on the present playback time
@objc func updateSlider() { // This perform will get known as above
guard let audioPlayer = audioPlayer else { return }
slider?.setValue(Float(audioPlayer.currentTime / audioPlayer.period), animated: true) // This line causes the stuttering
}
I’ve tried background DispatchQueue however it crashes the app saying slider.setvalue should be known as from important thread because it updates ui. I additionally tried taking part in audio within the background thread however that was a doomed thought to start with. Following is my audio supervisor code
import AVFAudio
import TvOSSlider
class AudioManager {
static let shared = AudioManager()
personal var audioPlayer: AVAudioPlayer?
var playbackTimer: Timer?
personal var isPaused = false
var slider: TvOSSlider? // Add a reference to the slider
personal init() { }
func playAudio(url: URL, completion: (() -> Void)? = nil) {
stopAudio()
do {
audioPlayer = strive AVAudioPlayer(contentsOf: url as URL)
audioPlayer?.prepareToPlay()
audioPlayer?.play()
isPaused = false
// Begin the playback timer to replace the search bar
DispatchQueue.important.async { [self] in
playbackTimer = Timer.scheduledTimer(timeInterval: 1.0, goal: self, selector: #selector(updateSlider), userInfo: nil, repeats: true)
}
completion?()
} catch let error as NSError {
print("Error initializing AVAudioPlayer: (error.localizedDescription)")
completion?()
}
}
func togglePlayPause() {
guard let audioPlayer = audioPlayer else {
return
}
if audioPlayer.isPlaying {
audioPlayer.pause()
playbackTimer?.invalidate()
playbackTimer = nil
isPaused = true
} else {
audioPlayer.play()
playbackTimer = Timer.scheduledTimer(timeInterval: 1.0, goal: self, selector: #selector(updateSlider), userInfo: nil, repeats: true)
isPaused = false
}
}
func stopAudio() {
audioPlayer?.cease()
audioPlayer = nil
isPaused = false
playbackTimer?.invalidate()
playbackTimer = nil
}
// MARK: - Slider strategies
// Replace the slider worth based mostly on the present playback time
@objc func updateSlider() {
guard let audioPlayer = audioPlayer else { return }
slider?.setValue(Float(audioPlayer.currentTime / audioPlayer.period), animated: true)
}
// Search to the specified place within the audio
@objc func sliderValueChanged(_ sender: TvOSSlider) {
guard let audioPlayer = audioPlayer else { return }
let targetTime = TimeInterval(sender.worth) * audioPlayer.period
audioPlayer.currentTime = targetTime
}
}
And right here is my use of this in my opinion controller
import TvOSSlider
class MyViewController: UIViewController {
...
@IBOutlet weak var tvosSlider: TvOSSlider!
override func viewDidLoad() {
tremendous.viewDidLoad()
setupView()
playSongFromUrl()
getData()
}
func setupView(){
// // Set the AudioManager's slider property
AudioManager.shared.slider = tvosSlider
AudioManager.shared.slider?.addTarget(AudioManager.shared, motion: #selector(AudioManager.sliderValueChanged(_:)), for: .valueChanged)
...
}
func play(url: URL) {
AudioManager.shared.playAudio(url: url){
self.stopLoader()
}
}
...
}
Now i’m unable to search out