SwiftAudio icon indicating copy to clipboard operation
SwiftAudio copied to clipboard

[Question] Get total duration

Open biesbjerg opened this issue 4 years ago • 6 comments

Is it possible to get total duration of a remote audio file?

By using the event updateDuration event the duration is continually updated (I think until everything has been downloaded/buffered?). This makes the knob on a seek bar/scrubber jump around until duration has been determined and are perceived quite buggy and hard to use by our users.

PS. Thanks for an awesome lib! :)

biesbjerg avatar Oct 27 '19 11:10 biesbjerg

Additional info: If I start playback of a file and take a look at the lock screen, the full duration is available even though I'm still getting updateDuration from SwiftAudio.

Tested on a device using iOS 13.

biesbjerg avatar Oct 29 '19 09:10 biesbjerg

I see that that the duration is available using player.duration at some point, but when is it safe to assume it is available? What's the purpose of event updateDuration that does not contain the total duration?

biesbjerg avatar Oct 30 '19 07:10 biesbjerg

The updateDuration event is called whenever the AVPlayerItem changes its duration. You can use this to know when the duration changes. If if seems to change abnormally I can take a look into it. The class that is the source of the event is the AVPlayerItemObserver.

To my knowledge you can assume that the player.duration is available when the state changes to ready

jorgenhenrichsen avatar Oct 31 '19 19:10 jorgenhenrichsen

In my case, updateDuration seems to update continuously. Looking a AVPlayerItemObserver it seems clear why.

Code:

player.event.stateChange.addListener(self) { [weak self] state in
	if ["ready", "playing"].contains(state.rawValue) {
		print("⌛ stateChange (to ready, playing) - player.duration: \(self?.player.duration)")
	}
}
player.event.updateDuration.addListener(self) { [weak self] duration in
	print("⌛ updateDuration: \(duration)")
}

Output:

⌛ stateChange (to ready, playing) - player.duration: Optional(1246.4848979591836)
⌛ updateDuration: 0.4963265306122449
⌛ updateDuration: 30.48307925
⌛ updateDuration: 67.341854761
⌛ updateDuration: 122.643079251
⌛ updateDuration: 158.822671088
⌛ updateDuration: 196.360630272
⌛ updateDuration: 233.245528232
⌛ updateDuration: 270.104303743
⌛ updateDuration: 306.963079254
⌛ updateDuration: 343.821854765
⌛ updateDuration: 380.680630276
⌛ updateDuration: 417.565528236
⌛ updateDuration: 454.424303747
⌛ updateDuration: 509.725528237
⌛ updateDuration: 546.584303748
⌛ updateDuration: 583.443079259
⌛ updateDuration: 637.359813954
⌛ updateDuration: 674.923895587
⌛ updateDuration: 711.782671098
⌛ updateDuration: 748.641446609
⌛ updateDuration: 803.942671099
⌛ updateDuration: 840.122262936
⌛ updateDuration: 877.66022212
⌛ updateDuration: 929.565528244
⌛ updateDuration: 965.745120081
⌛ updateDuration: 1002.603895592
⌛ updateDuration: 1039.462671103
⌛ updateDuration: 1076.321446614
⌛ updateDuration: 1111.821854778
⌛ updateDuration: 1168.481446615
⌛ updateDuration: 1205.340222126
⌛ updateDuration: 1246.4848979591836

I tried using player.duration when state changes to ready, but if you pass playWhenReady: true, state goes directly from loading to playing, never entering ready state. A workaround is to access player.duration when state changes to ready or playing, but that is not optimal.

biesbjerg avatar Oct 31 '19 20:10 biesbjerg

The updateDuration seems to work as intended, it is only intended to send events whenever the item updates its duration value. Does your scrub behave better with your PR #87 and using the player's ready state?

As for the incorrect state, that is interesting and definitely seems like a bug 🐛You can move it to a separate ticket and I will do some testing too 👍

jorgenhenrichsen avatar Nov 02 '19 09:11 jorgenhenrichsen

With the PR, I can access player.duration when ready and scrubbing works perfectly :)

I don't think I completely understand the updateDuration event though, if it's working as intended. Why does it emit intermediate duration values up until the final full duration when the full duration it is already on ready?

biesbjerg avatar Nov 02 '19 10:11 biesbjerg