iOS从avplayer获取音频时间
我是新来的ios,我有一个包含在线音频播放器的应用程序。我需要获得音频的总持续时间。我已经尝试了很多,但所有代码返回NaN或持续时间。什么是获得音频总持续时间的最佳方式..?iOS从avplayer获取音频时间
我的代码
NSString *songUrl = @"http://9xmusiq.com/songs2/tamil/Kaatru%20Veliyidai/Azhagiye%20%5bStarmusiq.cc%5d.mp3"
AVURLAsset *asset = [AVURLAsset assetWithURL:[NSURL URLWithString:songUrl]];
AVPlayerItem *playerItem1 = [AVPlayerItem playerItemWithAsset:asset];
AVPlayer *player1 = [AVPlayer playerWithPlayerItem:playerItem1];
AVPlayerLayer *playerLayer1 = [AVPlayerLayer playerLayerWithPlayer:player1];
playerLayer1.videoGravity = AVLayerVideoGravityResizeAspectFill;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
playerLayer1.frame = self.view.frame;
});
[self.view.layer insertSublayer:playerLayer1 atIndex:1];
[player1 play];
[playerItem1 addObserver:self forKeyPath:@"status" options:0 context:nil];
[playerItem1 addObserver:self forKeyPath:@"playbackBufferEmpty" options:0 context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([object isKindOfClass:[AVPlayerItem class]]){
AVPlayerItem *item = (AVPlayerItem *)object;
if ([keyPath isEqualToString:@"status"]){
switch(item.status){
case AVPlayerItemStatusFailed:
NSLog(@"player item status failed");
break;
case AVPlayerItemStatusReadyToPlay:
NSLog(@"player item status is ready to play");
Float64 duration = CMTimeGetSeconds(self.avPlayer.currentItem.duration);
NSLog(@"Duration--> %f",duration) // NaN returns
break;
case AVPlayerItemStatusUnknown:
NSLog(@"player item status is unknown");
break;
}
}else if ([keyPath isEqualToString:@"playbackBufferEmpty"]){
if (item.playbackBufferEmpty){
NSLog(@"player item playback buffer is empty");
}
}
}
}
感谢您的支持的朋友,最后我发现我的问题的解决方案,而不是使用AVPlayer我用AVAudioPlayer和我解决了问题,我得到了音频持续时间。
NSString* resourcePath = @"http://9xmusiq.com/songs2/tamil/Kaatru%20Veliyidai/Azhagiye%20%5bStarmusiq.cc%5d.mp3"; //your url
NSData *_objectData = [NSData dataWithContentsOfURL:[NSURL URLWithString:resourcePath]];
NSError *error;
AVAudioPlayer *player1 = [[AVAudioPlayer alloc] initWithData:_objectData error:&error];
player1.numberOfLoops = 0;
player1.volume = 1.0f;
[player1 prepareToPlay];
NSLog(@"Total Duration : %f",player1.duration);
if (player1 == nil){
NSLog(@"%@", [error description]);
}else{
[player1 play];
}
我不是那熟悉的AVPlayer
,但在它看起来像AVAsset
的文档周围挖(或你的情况AVURLAsset
)是保持持续的对象。
尝试查询资产:
AVURLAsset *asset = [AVURLAsset assetWithURL:[NSURL
URLWithString:songUrl]];
CMTime durationCMTime = asset.duration;
Float64 duration =
CMTimeGetSeconds(durationCMTime);
NSLog(@"Duration of asset is %f", duration);
您可以访问使用duration
财产AVPlayerItem
的资产的持续时间。如果您需要小数点后的精确秒数,请使用Float64
从CMTimeGetSeconds
接收时间。对于经常使用的情况,我想int
就足够了。
CMTime duration = playerItem1.asset.duration;
int durationTotalSeconds = CMTimeGetSeconds(duration);
int durationHours = floor(durationTotalSeconds/3600);
int durationMinutes = floor(durationTotalSeconds % 3600/60);
int durationSeconds = floor(durationTotalSeconds % 3600 % 60);
NSString *audioDurationString = [NSString stringWithFormat:@"%d:%d:%d",durationHours, durationMinutes, durationSeconds];
它看起来像CMTimeGetSeconds返回Float64(又名双精度)不是一个NSUInteger。 –
是的,我知道。我们隐式地强制类型转换以获得没有小数点的结果,仅仅用于普通的音频播放器用例。我编辑了我的答案来使用'int'。 –
好的,陷阱。这种自动改变类型在Swift中不合法,所以我开始这么想。 (就我个人而言,我更喜欢C的处理和标量类型的“自动提升”,以防止Swift僵硬的打字,但抵抗是徒劳的。) –
当你AVPlayer
准备打(的AVPlayerItemStatusReadyToPlay
的情况下),你可以使用
CMTime duration = self.player.currentItem.asset.duration;
float seconds = CMTimeGetSeconds(duration);
嘿,好友还是我得到了nan作为音频持续时间 – Sasi
就可以得到持续时间- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(nullable dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block;
@property(nonatomic,strong) AVPlayer *player;
@property(nonatomic,strong) id obsever;
self.player = [[AVPlayer alloc]initWithURL:URL];
[self.player play];
self.obsever = [self.player addPeriodicTimeObserverForInterval:interval queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {//you can get duration in block
CMTimeGetSeconds(theItem.currentTime);
CMTimeGetSeconds(theItem.duration)
}];
它适合你吗?因为这些代码不适合我。我仍然获得持续时间0,并不播放歌曲。你有其他的替代方法吗? – Moxarth