2013-12-23 105 views
0

我需要在我的應用程序中播放遠程mp3文件。我使用AVURLAssetAVPlayer來做到這一點。一切都很好,但有些文件的長度不正確。我需要正確的長度才能顯示曲目播放的進度條。AVAsset長度不正確

這裏是錯誤的長度的MP3文件: http://content.mts.stream.ru/files/melody/mp3/3828.mp3

這裏是我試圖讓軌道長度:

AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil]; 
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset]; 

Float64 assetDuration = CMTimeGetSeconds(asset.duration); 
Float64 itemDuration = CMTimeGetSeconds(item.duration); 

兩個assetDurationitemDuration是〜45秒。真實的軌道長度約爲30秒。

我怎樣才能得到真正的MP3文件的長度?看起來像是mp3標籤有錯誤,因爲我的Mac上的預覽工具也說它是45秒。然而iTunes說它是30秒。

我有一個想法,我可以得到HTTP響應的內容長度字段和計算軌道大小,但我需要得到比特率。

UPDATE

我去更深,試圖用AudioToolbox:

AudioFileID fileID; 
OSStatus result = AudioFileOpenURL((__bridge CFURLRef)url, kAudioFileReadPermission, 0, &fileID); 
UInt32 bitrate = 0; 
UInt32 bitrateSize = sizeof(UInt32); 
result = AudioFileGetProperty(fileID, kAudioFilePropertyBitRate, &bitrateSize, &bitrate); 

UInt64 size = 0; 
UInt32 sizeSize = sizeof(UInt64); 
result = AudioFileGetProperty(fileID, kAudioFilePropertyAudioDataByteCount, &sizeSize, &size); 

AudioFileClose(fileID); 

UInt64 seconds = size/(bitrate/8); 

,然後又錯誤值。所以看起來這個文件在編碼方面有一些問題。我會更新這個問題,如果我會得到進一步的結果。

回答

0

我發現了什麼是對當前項目的持續時間屬性使用志願準確: 添加觀察:

[item addObserver:self 
       forKeyPath:@"duration" 
        options:0 
        context:NULL]; 

刪除觀察:

@try { 
     [item removeObserver:self forKeyPath:@"duration"]; 
    } 

觀察方法:

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context{ 
    if ([keyPath isEqualToString:@"duration"] == YES){ 
     //playe item duration property should now be up to date 
    } 
} 
0

以上是對上述解決方案的改進(包括ng位深度):

func determineDuration(url: NSURL) -> NSTimeInterval { 
    var fileID: AudioFileID = AudioFileID() 
    AudioFileOpenURL(url, AudioFilePermissions.ReadPermission, 0, &fileID) 
    var bitrate: UInt32 = 0 
    var bitrateSize: UInt32 = UInt32(sizeof(UInt32)) 
    AudioFileGetProperty(fileID, kAudioFilePropertyBitRate, &bitrateSize, &bitrate) 

    var size: UInt64 = 0 
    var sizeSize: UInt32 = UInt32(sizeof(UInt64)) 
    AudioFileGetProperty(fileID, kAudioFilePropertyAudioDataByteCount, &sizeSize, &size) 

    var depth: UInt32 = 0 
    var depthSize: UInt32 = UInt32(sizeof(UInt32)) 
    AudioFileGetProperty(fileID, kAudioFilePropertySourceBitDepth, &depthSize, &depth) 

    AudioFileClose(fileID) 

    return NSTimeInterval(size/UInt64(bitrate/depthSize)) 
}