Cách giảm độ trễ khởi động AVPlayer trên iOS


115

Lưu ý, đối với câu hỏi dưới đây: Tất cả nội dung đều là cục bộ trên thiết bị - không có mạng trực tuyến nào diễn ra. Các video chứa các bản âm thanh.

Tôi đang làm việc trên một ứng dụng iOS yêu cầu phát tệp video với độ trễ tối thiểu để bắt đầu video clip được đề cập. Thật không may, chúng tôi không biết video clip cụ thể nào tiếp theo cho đến khi chúng tôi thực sự cần khởi động nó. Cụ thể: Khi một video clip đang phát, chúng ta sẽ biết bộ (đại khái) 10 video clip tiếp theo là gì, nhưng chúng ta không biết chính xác cái nào, cho đến khi 'phát ngay' đoạn tiếp theo.

Những gì tôi đã làm để xem xét độ trễ khi bắt đầu thực tế là gọi addBoundaryTimeObserverForTimestrình phát video, với khoảng thời gian là một phần nghìn giây để xem thời điểm video thực sự bắt đầu phát và tôi lấy sự khác biệt của dấu thời gian đó với vị trí đầu tiên trong mã cho biết nội dung nào sẽ bắt đầu chơi.

Từ những gì tôi đã thấy cho đến nay, tôi nhận thấy rằng việc sử dụng kết hợp AVAssettải và sau đó tạo một AVPlayerItemtừ đó khi nó đã sẵn sàng và sau đó chờ AVPlayerStatusReadyToPlaytrước khi tôi gọi phát, có xu hướng mất từ ​​1 đến 3 giây để bắt đầu kẹp.

Kể từ đó, tôi đã chuyển sang thứ mà tôi nghĩ gần như tương đương: gọi điện [AVPlayerItem playerItemWithURL:]và chờ AVPlayerItemStatusReadyToPlaychơi. Hiệu suất gần giống nhau.

Một điều tôi đang quan sát là tải mục AVPlayer đầu tiên chậm hơn phần còn lại. Có vẻ như một ý tưởng là chạy trước AVPlayer với nội dung ngắn / trống trước khi cố gắng phát video đầu tiên có thể là thông lệ tốt. [ Khởi động chậm cho AVAudioPlayer trong lần đầu tiên phát âm thanh

Tôi muốn giảm thời gian bắt đầu video xuống càng nhiều càng tốt và có một số ý tưởng về những điều cần thử nghiệm, nhưng tôi muốn một số hướng dẫn từ bất kỳ ai có thể giúp đỡ.

Cập nhật: ý tưởng 7, bên dưới, khi được triển khai mang lại thời gian chuyển đổi khoảng 500 mili giây. Đây là một cải tiến, nhưng sẽ rất tuyệt nếu bạn làm được điều này nhanh hơn nữa.

Ý tưởng 1: Sử dụng N AVPlayers (sẽ không hoạt động)

Sử dụng ~ 10 AVPPlayerđối tượng và bắt đầu và tạm dừng tất cả ~ 10 clip, và khi chúng tôi biết mình thực sự cần cái nào, hãy chuyển sang và bỏ tạm dừng đúng AVPlayer, và bắt đầu lại cho chu kỳ tiếp theo.

Tôi không nghĩ rằng điều này hoạt động, bởi vì tôi đã đọc có khoảng giới hạn 4 hoạt động AVPlayer'strong iOS. Có ai đó hỏi về điều này trên StackOverflow ở đây và đã tìm hiểu về giới hạn 4 AVPlayer: chuyển đổi nhanh-giữa các video-sử dụng-avfoundation

Ý tưởng 2: Sử dụng AVQueuePlayer (sẽ không hoạt động)

Tôi không tin rằng việc nhét 10 AVPlayerItemsvào một AVQueuePlayersẽ tải trước tất cả chúng để bắt đầu liền mạch. AVQueuePlayerlà một hàng đợi và tôi nghĩ nó thực sự chỉ làm cho video tiếp theo trong hàng đợi sẵn sàng để phát lại ngay lập tức. Tôi không biết video nào trong số ~ 10 video mà chúng tôi muốn phát lại, cho đến khi bắt đầu video đó. ios-avplayer-video-tải trước

Ý tưởng 3: Tải, Phát và giữ lại AVPlayerItemstrong nền (chưa chắc chắn 100% - nhưng có vẻ không đẹp)

Tôi đang xem liệu có lợi ích gì khi tải và phát giây đầu tiên của mỗi video clip trong nền (ngăn chặn đầu ra video và âm thanh), đồng thời giữ tham chiếu đến từng video AVPlayerItemvà khi chúng tôi biết mục nào cần được phát thực, hoán đổi cái đó trong và hoán đổi AVPlayer nền với cái đang hoạt động. Rửa sạch và lặp lại.

Lý thuyết cho rằng những bản phát gần đây AVPlayer/AVPlayerItemvẫn có thể chứa một số tài nguyên đã chuẩn bị sẵn để làm cho việc phát lại sau đó nhanh hơn. Cho đến nay, tôi chưa thấy lợi ích từ điều này, nhưng có thể tôi chưa AVPlayerLayerthiết lập chính xác cho nền. Tôi nghi ngờ điều này sẽ thực sự cải thiện mọi thứ từ những gì tôi đã thấy.

Ý tưởng 4: Sử dụng một định dạng tệp khác - có thể là một định dạng tải nhanh hơn?

Tôi hiện đang sử dụng định dạng H.264 của .m4v (video-MPEG4). H.264 có rất nhiều tùy chọn codec khác nhau, vì vậy có thể một số tùy chọn được tìm kiếm nhanh hơn những tùy chọn khác. Tôi nhận thấy rằng việc sử dụng các cài đặt nâng cao hơn làm cho kích thước tệp nhỏ hơn sẽ làm tăng thời gian tìm kiếm, nhưng không tìm thấy bất kỳ tùy chọn nào theo hướng khác.

Ý tưởng 5: Kết hợp định dạng video không mất dữ liệu + AVQueuePlayer

Nếu có một định dạng video tải nhanh nhưng có thể kích thước tệp quá lớn, một ý tưởng có thể là chuẩn bị trước 10 giây đầu tiên của mỗi video clip với một phiên bản cồng kềnh nhưng tải nhanh hơn, nhưng quay lại với nội dung được mã hóa trong H.264. Sử dụng AVQueuePlayer và thêm 10 giây đầu tiên ở định dạng tệp không nén và tiếp theo với định dạng tệp ở H.264, có thời gian chuẩn bị / tải trước lên đến 10 giây. Vì vậy, tôi muốn nhận được 'điều tốt nhất' của cả hai thế giới: thời gian bắt đầu nhanh, nhưng cũng được hưởng lợi từ định dạng nhỏ gọn hơn.

Ý tưởng 6: Sử dụng AVPlayer không chuẩn / viết của riêng tôi / sử dụng của người khác

Theo nhu cầu của tôi, có lẽ tôi không thể sử dụng AVPlayer, nhưng phải sử dụng AVAssetReader và giải mã trong vài giây đầu tiên (có thể ghi tệp thô vào đĩa) và khi phát lại, hãy sử dụng định dạng thô để phát nó trở lại nhanh chóng. Có vẻ như đây là một dự án lớn đối với tôi, và nếu tôi thực hiện nó một cách ngây thơ, thì nó không rõ ràng / thậm chí không có khả năng hoạt động tốt hơn. Mỗi khung video được giải mã và không nén là 2,25 MB. Nói một cách ngây thơ - nếu chúng tôi sử dụng ~ 30 khung hình / giây cho video, tôi sẽ kết thúc với yêu cầu đọc từ đĩa ~ 60 MB / s, điều này có lẽ là không thể / đẩy được. Rõ ràng là chúng ta sẽ phải thực hiện một số cấp độ nén hình ảnh (có lẽ là định dạng nén openGL / es bản địa thông qua PVRTC) ... nhưng điều đó thật điên rồ. Có lẽ có một thư viện ngoài đó mà tôi có thể sử dụng?

Ý tưởng 7: Kết hợp mọi thứ thành một nội dung phim duy nhất và seekToTime

Một ý tưởng có thể dễ dàng hơn một số ý tưởng ở trên, là kết hợp mọi thứ vào một bộ phim duy nhất và sử dụng seekToTime. Vấn đề là chúng tôi sẽ nhảy khắp nơi. Thực chất là truy cập ngẫu nhiên vào phim. Tôi nghĩ điều này thực sự có thể giải quyết ổn thỏa: avplayer-movie-play-lag-in-ios5

Bạn nghĩ cách tiếp cận nào sẽ là tốt nhất? Cho đến nay, tôi đã không đạt được nhiều tiến bộ trong việc giảm độ trễ.


Đối với những gì nó đáng giá, tôi sẽ sử dụng Ý tưởng 7. Nó vẫn chậm, nhưng không chậm không thể đoán trước như các lựa chọn khác. Câu hỏi tiếp theo mà tôi có là - các tùy chọn codec, độ phân giải và tần số khung hình chính có ảnh hưởng đến thời gian tìm kiếm không?
Bernt Habermeier

Trễ trò chơi, nhưng có thể đáng để chuyển đổi video càng nhanh càng tốt (tức là ngay sau khi video mới bắt đầu phát) và lập hồ sơ ứng dụng để xem nơi nó dành phần lớn thời gian cho CPU.
tc.

1
Gần một năm sau, bạn đã từng tìm ra điều gì với điều này?
lnafziger

1
Tôi đã đi với tùy chọn 7 và đến một nơi nào đó trong khoảng từ 300ms đến 500ms tìm kiếm. Một điều tôi nhận thấy là các tùy chọn codec mp4 càng phức tạp thì seekTo càng chậm. Có một số tùy chọn nén video cho phép nén tốt hơn và duy trì chất lượng video, nhưng giết thời gian giải mã.
Bernt Habermeier

2
Đó là một yêu cầu nghe có vẻ hợp lý, nhưng thực sự để thực hiện phương án 7, có quá nhiều khía cạnh trong việc triển khai để đăng tải. Cân nhắc: (a) Tạo chuỗi công cụ để hợp nhất nội dung video, (b) đảm bảo bạn theo dõi các hiệu số phân đoạn video, (c) các hiệu ứng tra cứu khi có yêu cầu phát một clip cụ thể, (d) sử dụng addPeriodicTimeObserverForInterval để kiểm tra nếu bạn chạy video clip và phản ứng tương ứng (sử dụng phương pháp này so với addBoundaryTimeObserverForTimes một lần quay bởi vì tôi nhận thấy rằng cái sau đôi khi không kích hoạt ... nói chung, điều này không phù hợp với việc dán mã.
Bernt Habermeier

Câu trả lời:


4

Đối với iOS 10.x trở lên để giảm độ trễ bắt đầu AVPlayer, tôi đã đặt: avplayer.automaticallyWaitsToMinimizeStalling = false; và điều đó dường như đã khắc phục được cho tôi. Điều này có thể gây ra những hậu quả khác, nhưng tôi chưa đánh trúng chúng.

Tôi lấy ý tưởng cho nó từ: https://stackoverflow.com/a/50598525/9620547


Tôi đã giảm được 6-7 giây độ trễ. Nhưng tôi có một câu hỏi ở đây, liệu nó có ảnh hưởng đến hiệu suất ứng dụng không?
kalpa

@kalpa Chúng tôi đã sử dụng mã này trong một ứng dụng sản xuất hơn một năm mà không có bất kỳ tác động tiêu cực nào rõ ràng. Chúng tôi chủ yếu phát các tệp âm thanh 20-60 phút cho người nghe ở Hoa Kỳ, nơi dữ liệu di động phủ sóng nói chung là nhanh. Tuy nhiên, trường hợp sử dụng của bạn có thể khác.
Grizzb

Cảm ơn bạn về thông tin. @grizzb
kalpa

1

Nội dung có thể không sẵn sàng sau khi bạn tạo, nó có thể thực hiện các tính toán như thời lượng của phim, hãy đảm bảo chứa tất cả siêu dữ liệu của phim trong tệp.


1

Trước tiên, bạn nên thử tùy chọn số 7 để xem liệu bạn có thể làm điều đó hoạt động hay không. Tôi nghi ngờ rằng nó sẽ không thực sự hoạt động cho nhu cầu của bạn vì thời gian tìm kiếm có thể sẽ không đủ nhanh để cung cấp cho bạn chuyển đổi liền mạch giữa các clip. Nếu bạn thử mà không thành công, thì tôi khuyên bạn nên thực hiện tùy chọn 4/6 và xem thư viện iOS của tôi được thiết kế đặc biệt cho mục đích này, chỉ cần thực hiện tìm kiếm nhanh trên google trên AVAnimator để tìm hiểu thêm. Thư viện của tôi giúp bạn có thể thực hiện các vòng lặp liền mạch và chuyển từ clip này sang clip khác, rất nhanh vì video phải được giải mã thành tệp trước khi xử lý. Trong trường hợp của bạn, tất cả 10 video clip sẽ được giải mã thành các tệp trước khi bạn bắt đầu, nhưng sau đó chuyển đổi giữa chúng sẽ rất nhanh.


Còn về phần âm thanh của video? Tôi cần video và âm thanh được đồng bộ hóa.
Bernt Habermeier

Có, âm thanh đã được xử lý với sự đồng bộ rất chặt chẽ giữa bản âm thanh và video clip. Xem các dự án xcode ví dụ. Tất cả đều đã được triển khai, bạn chỉ cần tải về và dùng thử.
MoDJ

Có khả năng phát video mạng bằng AVAnimator không?
Richard Topchii

Không, nó hoạt động trên các tệp cục bộ, video mạng trực tuyến là một điều hoàn toàn khác.
MoDJ

0

Chưa từng làm bất cứ điều gì như thế này trong quá khứ, dựa trên suy nghĩ và kinh nghiệm của bạn, tôi sẽ thử kết hợp 7 và 1: Tải trước một AVPlayer với vài giây đầu tiên trong số 10 video tiếp theo. Sau đó, việc bỏ qua sẽ rất có thể nhanh hơn và đáng tin cậy hơn do ít dữ liệu hơn. Trong khi bạn đang phát phần đã chọn, bạn có đủ thời gian để chuẩn bị AVPlayer cho phần còn lại của video tiếp theo đã chọn trong nền. Khi phần đầu kết thúc, bạn chuyển sang AVPlayer đã chuẩn bị. Vì vậy, tổng cộng, bạn có thể tải tối đa 2 AVPlayers tại bất kỳ thời điểm nào.

Tất nhiên tôi không biết liệu việc chuyển đổi có thể được thực hiện trơn tru đến mức không làm phiền quá trình phát lại hay không.

(Tôi sẽ thêm điều này làm bình luận nếu tôi có thể.)

Tốt nhất, Peter


Tôi không tìm thấy lợi ích nào của việc tải hàng loạt 10 nội dung trên một AVPlayer. Hơn nữa, tôi không hiểu đề xuất của bạn, vì tôi thấy tùy chọn (1) và (7) loại trừ lẫn nhau. Tùy chọn 7 hợp nhất tất cả nội dung video thành một nội dung - do đó chỉ có một nội dung duy nhất để tải thời gian. Đây là những gì tôi đang làm hôm nay và đáng giá là tôi nhận được độ trễ khoảng 500 mili giây về thời gian bắt đầu / phát thực tế. Điều đáng chú ý là SeekTo hoàn thành nhanh hơn so với khung hình đầu tiên thực tế được phát, vì vậy đối với thời gian bắt đầu thực sự, tôi đo thời điểm khung hình đầu tiên thực sự phát lại thông qua gọi lại theo thời gian.
Bernt Habermeier

Chỉ để làm rõ ý tưởng của tôi: Ý tưởng của tôi là chia nội dung thành hai phần: vài giây đầu tiên và phần còn lại. Bây giờ bạn đã tạo ra hai tài sản từ một. 10 phần bắt đầu bạn tham gia và sử dụng bỏ qua và trong khi chơi phần đầu, bạn sẽ tải phần còn lại. Sau đó, điều này bao gồm đề xuất 8 sẽ thêm vào danh sách của bạn.
ilmiacs

Nhưng như tôi hiểu từ nhận xét cuối cùng của bạn, trong khi đó bạn đã thúc đẩy nghiên cứu sâu hơn, điều đó là tốt, và giải pháp 7 cũng không hoạt động. Có vẻ như AV về cơ bản vẫn cản đường bạn và cách duy nhất để bạn đi có lẽ là sử dụng công nghệ bên dưới, đó là Core Media, để kiểm soát nhiều hơn nội dung của bạn. Peter.
ilmiacs

Ồ, tôi hiểu ý bạn hơn bây giờ. Cảm ơn. Sẽ rất thú vị khi điều tra nếu bạn nhận được thời gian tìm kiếm nhanh cho các video clip ngắn. Tôi chưa thử điều đó, nhưng sẽ đáng để xem xét. Về việc sử dụng phương tiện cốt lõi - tôi không tìm thấy bất kỳ tài liệu tham khảo tốt nào về API đó. Bạn có nguồn thông tin tốt có thể chỉ cho tôi không?
Bernt Habermeier

Không, xin lỗi. Như tôi đã nói, tôi không phải là chuyên gia về AV hay Core Media. Chỉ cần đọc Câu hỏi của bạn và có một số ý tưởng về cách cá nhân tôi sẽ tiến hành và muốn chia sẻ chúng. Peter
ilmiacs

0

Nếu tôi hiểu chính xác vấn đề của bạn, có vẻ như bạn có một video liên tục mà bạn cần tải bản âm thanh cho một lúc.

Nếu đó là trường hợp, tôi khuyên bạn nên xem xét BASS . BASS là một thư viện âm thanh giống như AVPlayer cho phép bạn (tương đối) dễ dàng truy cập vào API cấp thấp của khung AudioUnits trong iOS. Điều gì có nghĩa là cho bạn? Nó có nghĩa là với một chút thao tác đệm (bạn thậm chí có thể không cần, tùy thuộc vào mức độ trễ nhỏ mà bạn muốn), bạn có thể bắt đầu phát nhạc ngay lập tức.

Tuy nhiên, những hạn chế mở rộng đối với video, như tôi đã nói, nó là một thư viện âm thanh nên bất kỳ thao tác video nào sẽ vẫn phải được thực hiện với AVPlayer. Tuy nhiên, bằng cách sử dụng, -seekToTime:toleranfeBefore:toleranceAfter:bạn có thể đạt được khả năng tìm kiếm nhanh trong video miễn là bạn đọc trước tất cả các tùy chọn cần thiết.

Nếu bạn đang đồng bộ hóa trên nhiều thiết bị (mà ứng dụng của bạn có thể đề xuất), chỉ cần để lại nhận xét và tôi rất sẵn lòng chỉnh sửa câu trả lời của mình.

Tái bút: BASS thoạt nhìn có vẻ khó khăn vì nó có định dạng giống C, nhưng nó thực sự rất dễ sử dụng.


-2

Dưới đây là một số thuộc tính và phương thức được cung cấp bởi lớp AVAsset có thể giúp:

- (void)_pu_setCachedDuration:(id)arg1;
- (id)pu_cachedDuration; 
- (struct
 { 
   long long x1; 
   int x2;
   unsigned int x3; 
   long long x4; 
})pu_duration;
- (void)pu_loadDurationWithCompletionHandler:(id /* block */)arg1;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.