2013-09-27 50 views
27

Tôi đã đoạn mã sau vào ứng dụng của tôi:iOS 7 AVPlayer AVPlayerItem thời gian không chính xác trong iOS 7

NSURL *url = [NSURL fileURLWithPath: [self.DocDir stringByAppendingPathComponent: self.FileName] isDirectory: NO]; 
self.avPlayer = [AVPlayer playerWithURL: url]; 

Float64 duration = CMTimeGetSeconds(self.avPlayer.currentItem.duration); 

này làm việc tốt với iOS 6 nhưng với iOS 7 vì một lý do nó sẽ trả về NaN. Khi kiểm tra self.avPlayer.currentItem.duration đối tượng CMTime có 0 với cờ là 17.

Điều thú vị là trình phát hoạt động tốt, chỉ thời gian là sai.

Có ai khác gặp phải sự cố tương tự không? Tôi đang nhập khẩu như sau:

#import <Foundation/Foundation.h> 
#import <AVFoundation/AVFoundation.h> 
#import <MediaPlayer/MediaPlayer.h> 
#import <CoreMedia/CoreMedia.h> 
#import <AVFoundation/AVAsset.h> 

Trả lời

48

Sau khi chơi xung quanh với nhiều cách khác nhau của khởi tạo các đối tượng tôi đến một giải pháp làm việc:

AVURLAsset *asset = [AVURLAsset assetWithURL: url]; 
Float64 duration = CMTimeGetSeconds(asset.duration); 
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset: asset]; 
self.avPlayer = [[AVPlayer alloc] initWithPlayerItem: item]; 

Nó xuất hiện giá trị thời gian không phải lúc nào cũng có sẵn ngay từ AVPlayerItem nhưng nó có vẻ hoạt động tốt với một AVAsset ngay lập tức.

+0

Xin chào Điều này không hiệu quả đối với tôi. bất kỳ lựa chọn thay thế nào khác? – Nitesh

+0

Xin chào Nitesh, vui lòng đặt câu hỏi của bạn trong một chuỗi mới, hiển thị một số mã của bạn và lỗi bạn đang nhận được. –

+2

Tôi cũng đang sử dụng [[AVPlayer currentItem] duration] trả về NaN trong iOS 7 cho các tệp phương tiện hợp lệ. Trong iOS 6 nếu nó trả về NaN, điều đó có nghĩa là tệp không thể phát được. Chuyển sang ý tưởng AVURLAsset sẽ sửa lỗi này. – Deminetix

24

Trong iOS 7, cho AVPlayerItem đã tạo ra, bạn cũng có thể có được khoảng thời gian từ tài sản underlaying:

CMTimeGetSeconds([[[[self player] currentItem] asset] duration]); 

Thay vì nhận được nó trực tiếp từ AVPlayerItem, mang đến cho bạn một NaN:

CMTimeGetSeconds([[[self player] currentItem] duration]); 
+0

Cảm ơn vì điều này! – JKoko

+0

tuyệt vời! THANKS – SpaceDog

4

Cách được khuyến nghị thực hiện việc này, như được mô tả trong the manual là bằng cách quan sát trạng thái mục trình phát:

[self.avPlayer.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionInitial context:nil]; 
.210

Sau đó, bên trong observeValueForKeyPath:ofObject:change:context:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    // TODO: use either keyPath or context to differentiate between value changes 
    if (self.avPlayer.currentItem.status == AVPlayerStatusReadyToPlay) { 
     Float64 duration = CMTimeGetSeconds(self.avPlayer.currentItem.duration); 
     // ... 
    } 
} 

Ngoài ra, hãy chắc chắn rằng bạn loại bỏ các quan sát viên khi bạn thay đổi các mục chơi:

if (self.avPlayer.currentItem) { 
    [self.avPlayer.currentItem removeObserver:self forKeyPath:@"status"]; 
} 

Btw, bạn cũng có thể quan sát duration sở hữu trực tiếp; tuy nhiên, đó là trải nghiệm cá nhân của tôi rằng kết quả không đáng tin cậy như chúng phải ;-)

+0

Đáng buồn là điều này không hoạt động trong iOS 10.x – user3069232

+0

@ user3069232 bởi "không hoạt động", ý bạn là gì? quan sát của bạn là gì? –

+0

Nó trả về nan ... Tôi đã kết thúc bằng việc sử dụng kết hợp AVURLAsset và trạng thái AVPlayer mà bạn đã sử dụng ở đây để làm cho nó hoạt động. – user3069232

Các vấn đề liên quan