【问题标题】:AVAsset incorrect lengthAVAsset 长度不正确
【发布时间】:2013-12-23 10:37:56
【问题描述】:

我需要在我的应用中播放远程 mp3 文件。我正在使用AVURLAssetAVPlayer 来做到这一点。一切都很好,但有些文件的长度不正确。我需要正确的长度来显示曲目播放的进度条。

这是长度错误的 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 响应的内容长度字段并计算轨道大小,但我需要获取比特率。

更新

我已经更深入并尝试使用 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);

又得到了错误的值。所以看起来这个文件有一些编码问题。如果我能得到进一步的结果,我会更新这个问题。

【问题讨论】:

    标签: ios mp3 avplayer avasset


    【解决方案1】:

    我发现准确的是在当前项目的持续时间属性上使用 KVO: 添加观察:

    [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
        }
    }
    

    【讨论】:

      【解决方案2】:

      这是对上述解决方案的改进(包括位深度):

      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))
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多