2012-07-13 20 views
27

Tôi có AVPlayer đang phát luồng video HLS. Giao diện người dùng của tôi cung cấp một hàng nút, một cho mỗi "chương" trong video (các nút được gắn nhãn "1", "2", "3"). Ứng dụng tải xuống một số siêu dữ liệu từ máy chủ chứa danh sách các điểm cắt chương được biểu thị bằng giây. Ví dụ: một video dài 12 phút - danh sách các điểm cắt chương là 0, 58, 71, 230, 530, v.v.AVPlayer seekToTime không phát ở đúng vị trí

Khi người dùng nhấn vào một trong các nút "chương" mã trình xử lý nút thực hiện điều này:

  [self.avPlayer pause]; 

    [self.avPlayer seekToTime: CMTimeMakeWithSeconds(seekTime, 600) 
       toleranceBefore: kCMTimeZero 
       toleranceAfter: kCMTimeZero 
      completionHandler: ^(BOOL finished) 
      { 
       [self.avPlayer play]; 
      }]; 

Trường hợp "seekTime" là một biến cục bộ chứa điểm cắt (như được mô tả ở trên).

Sự cố là video không phải lúc nào cũng bắt đầu tại điểm chính xác. Đôi khi nó. Nhưng đôi khi nó là bất cứ nơi nào từ một phần mười giây, đến 2 giây TRƯỚC KHI thời gian tìm kiếm được yêu cầu. Nó KHÔNG BAO GIỜ bắt đầu sau thời gian tìm kiếm được yêu cầu.

Dưới đây là một số thống kê về mã hóa video:

mã hóa: handbrakeCLI Codec: h.264 Frame rate: 24 (trên thực tế, 23,976 - giống như cách nó đã bị bắn) Video Bitrate: nhiều bitrate (64/150/300/500/800/1200) Audio Bitrate: 128k Khung hình: 23,976 (1 per second)

tôi đang sử dụng các công cụ của Apple mediafilesegmenter, tất nhiên, và variantplaylistcreator để tạo danh sách nhạc.

Các tệp đang được phân phát từ nhóm Amazon Cloud/S3.

Một lĩnh vực mà tôi vẫn chưa rõ ràng là CMTimeMakeWithSeconds - Tôi đã thử một số biến thể dựa trên các bài viết/tài liệu khác nhau mà tôi đã đọc. Ví dụ, trong đoạn trích trên, chúng tôi đang sử dụng:

CMTimeMakeWithSeconds (seekTime, 600)

Tôi cũng đã cố gắng:

CMTimeMakeWithSeconds (seekTime, 1)

tôi không thể nói đó là chính xác, mặc dù BOTH dường như tạo ra các kết quả không phù hợp!

Tôi cũng đã cố gắng:

CMTimeMakeWithSeconds (seekTime, 23,967)

Một số bài báo tuyên bố này hoạt động giống như một tử số/denomenator, vì vậy n/1 nên được đúng nơi 'n' là số giây (như trong CMTimeMakeWithseconds (n, 1)). Tuy nhiên, mã ban đầu được tạo ra bởi một lập trình viên khác (người đã biến mất bây giờ) và ông đã sử dụng số 600 cho priorityTimeScale (ví dụ: CMTimeMakeWithseconds (n, 600)).

Có ai có thể cung cấp bất kỳ manh mối nào về những gì tôi đang làm sai hay thậm chí nếu loại chính xác mà tôi đang cố gắng đạt được thậm chí có thể?

Và trong trường hợp ai đó bị cám dỗ cung cấp giải pháp "thay thế", chúng tôi đã xem xét vi phạm video thành các luồng riêng biệt, mỗi chương, nhưng chúng tôi không tin rằng sẽ cho chúng ta hiệu suất tương tự theo nghĩa là thay đổi các chương sẽ mất nhiều thời gian hơn vì một AVPlayerItem mới sẽ phải được tạo và tải, v.v., v.v.Vì vậy, nếu bạn nghĩ rằng đây là giải pháp duy nhất sẽ hoạt động (và chúng tôi hy vọng điều này sẽ đạt được kết quả chúng tôi muốn - tức là mỗi chương SILL bắt đầu chính xác nơi chúng tôi muốn) cảm thấy tự do để nói như vậy.

Cảm ơn trước!

Trả lời

2

vui lòng sử dụng chức năng như [player seekToTime:CMTimeMakeWithSeconds(seekTime,1)].
Vì giá trị dung sai của bạn kCMTimeZero sẽ mất nhiều thời gian hơn để tìm kiếm.Khi sử dụng giá trị dung sai của kCMTimeZero bạn có thể sử dụng kCMTimeIndefinite tương đương với hàm tôi đã chỉ định trước đó.

+0

Tôi xin lỗi, nhưng làm cách nào để trả lời câu hỏi này? –

+1

Sai. Một khoảng thời gian 1 có nghĩa là bạn chỉ có thể chỉ định toàn bộ giây để tìm kiếm. Thời gian là số phần trên giây. Sử dụng 600 cho video, như Apple khuyến cáo, vì nó là một sản phẩm của các tỷ lệ khung hình video phổ biến như 50, 60, 25 và 24 khung hình mỗi giây. –

3

Đề xuất của tôi: 1) Không sử dụng [avplayer seekToTime: toleranceBefore: toleranceAfter:], điều này sẽ làm chậm thời gian tìm kiếm của bạn 4-5 giây.

2) Cắt video HLS thành 10 giây trên mỗi đoạn. Chương bắt đầu chương của bạn phải phù hợp với giá trị đó là số nhiều của 10. Khi phân đoạn bắt đầu với tôi khung, theo cách này, bạn có thể nhận được thời gian tìm kiếm nhanh chóng và thời gian chính xác.

+7

Nếu không sử dụng '[avplayer seekToTime: toleranceBefore: toleranceAfter:]' thì phương pháp nào nên được sử dụng? – Fennelouski

+1

Tôi không đồng ý với điều này. Câu hỏi là "AVPlayer seekToTime không phát ở vị trí chính xác". Bằng cách thêm các toleranceBefore: toleranceAfter: các tham số tới seekToTime() được đặt thành kCMTimeZero, bạn sẽ giải quyết vấn đề này, vì vậy đó là một câu trả lời đúng cho câu hỏi. Nếu bạn không sử dụng điều này, nó là tùy ý nơi người chơi bắt đầu. – Bocaxica

+0

Cảm ơn bạn đã chỉ ra điều này, tôi đã giải quyết được sự cố Lag bằng phương pháp thay thế. –

76
int32_t timeScale = self.player.currentItem.asset.duration.timescale; 
CMTime time = CMTimeMakeWithSeconds(77.000000, timeScale); 
[self.player seekToTime:time toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero]; 

Tôi gặp sự cố với 'seekToTime'. Tôi giải quyết vấn đề của tôi với mã này. 'timescale' là thủ thuật cho vấn đề này.

+6

@ jordan-bigel này nên được chọn làm câu trả lời đúng. –

+0

giải pháp tốt đẹp @Muhmd –

+0

Cảm ơn người đàn ông, nó đã lưu một ngày của tôi, –

0

Đặt mã này có thể giải quyết được sự cố của bạn.

let targetTime = CMTimeMakeWithSeconds(videoLastDuration, 1) // videoLastDuration hold the previous video state. 
self.playerController.player?.currentItem?.seekToTime(targetTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)