Error in MoviePlayer.duration on Mac

I have a program using the MoviePlayer to play MP3 files that works in Windows. When ported to the Mac, the file plays but calls to AudioPlayer.duration return NaN. Is this a known problem and is there a solution?

How to reproduce this?

Maybe you make a sample project and report via Feedback app a problem?

As far as I recall, at least on the Mac, .duration returns a valid number AFTER the file has started playing.
An alternate way is to use MacOSlibrary (there is also a 64bit version), passing the folderitem:
dim asset as AVAsset = AVAsset.AssetWithURL( new NSURL( f ) )
Return asset.DurationInSeconds

AVAsset loads asynchronously, so you can do do like this:

[code]dim f as FolderItem = SpecialFolder.Desktop.Child(“test.m4v”)
dim a as AVAssetMBS = AVAssetmbs.assetWithFile(f)

if a = nil then
MsgBox “failed to read file at all”
end if

// request duration property
a.loadValuesAsynchronouslyForKeys array(“duration”)

dim e as NSErrorMBS
dim Status as Integer = a.statusOfValueForKey(“duration”, e)
while status < a.AVKeyValueStatusLoaded
// wait for loading in background
status = a.statusOfValueForKey(“duration”, e)

// got it?
if status <> a.AVKeyValueStatusLoaded then
MsgBox “Failed to load duration.”
if e <> nil then
MsgBox e.LocalizedDescription
end if

MsgBox str(a.duration.Seconds)+" seconds long."
end if[/code]

If you use

dim asset as AVAssetMBS = MoviePlayer1.AVAssetMBS

you get the asset from the movie player.

Thanks Carlo and Christian,

I plan to learn more about AVAssets. After sleeping on the problem, I found a simple solution. This doesn’t work:

FDuration = AudioPlayer.Duration
DurationTextField.text = TimeString(FDuration)

Apparently, in contrast to Windows, the Apple player needs to time gather its wits. This construct works:

DurationTimer.mode = Timer.ModeSingle

The DurationTimer has a period of 250 ms and the following action:

FDuration = AudioPlayer.Duration
DurationTextField.text = TimeString(FDuration)


what about putting the code in the play event of the movieplayer? Something like:
if durationTextField.text = “” then
durationTextField.text = timeString(FDuration)
end if

AVFoundation is Asynchronous in nature, in this case it does mean you have to do extra work to make sure that the information is loaded. The idea behind it is that you can load and start playing an asset much quicker.

AVFoundation is interesting to say the least, after doing some work with Apple’s old QuickTime, AVFoundation is overly complicated and you really need to learn it’s quirks otherwise you’re left scratching your head for a long time.

Something as simple as loading a movie and extracting a single frame, on some movies this just works on others it downright refused to give me the frame at the time I wanted. Turned out I needed to set a flag when loading the movie, then I also needed to specify a time variance of zero.

This is the first time I’ve ever heard compliments for the QuickTime APIs. Having maintained and updated our QuickTime-related code, I definitely don’t agree.

@Joe Ranieri - for me, you did such a good job of simplifying the QT APIs at the RB/RS layer that I didn’t need to worry about the same level of minutia that AVFoundation presents. May have been more frustrating at your end, but you did a great job in hiding that from us.

The problem may be that AVFoundation is so asynchronous.
Having synchronous options would benefit the beginners.