ExoPlayer phát hầu hết các luồng phát trực tiếp thích ứng mà không cần bất kỳ cấu hình đặc biệt nào. Hãy xem trang Định dạng được hỗ trợ để biết thêm thông tin chi tiết.
Sự kiện phát trực tiếp thích ứng cung cấp một cửa sổ chứa nội dung nghe nhìn có sẵn và được cập nhật theo các khoảng thời gian đều đặn để phù hợp với thời gian thực hiện tại. Điều đó có nghĩa là vị trí phát sẽ luôn nằm trong khoảng thời gian này, trong hầu hết các trường hợp là gần với thời gian thực hiện tại mà luồng phát đang được tạo. Khoảng chênh lệch giữa thời gian thực hiện tại và vị trí phát được gọi là độ lệch phát trực tiếp.
Phát hiện và giám sát nội dung phát trực tiếp
Mỗi khi cửa sổ trực tiếp được cập nhật, các thực thể Player.Listener đã đăng ký sẽ nhận được một sự kiện onTimelineChanged. Bạn có thể truy xuất thông tin chi tiết về chế độ phát trực tiếp hiện tại bằng cách truy vấn nhiều phương thức Player và Timeline.Window, như được liệt kê bên dưới và minh hoạ trong hình sau.

Player.isCurrentWindowLivecho biết liệu mục nội dung nghe nhìn đang phát có phải là sự kiện phát trực tiếp hay không. Giá trị này vẫn đúng ngay cả khi sự kiện phát trực tiếp đã kết thúc.Player.isCurrentWindowDynamiccho biết liệu mục nội dung đa phương tiện đang phát có còn được cập nhật hay không. Điều này thường đúng đối với những sự kiện phát trực tiếp chưa kết thúc. Xin lưu ý rằng cờ này cũng đúng đối với các video không phát trực tiếp trong một số trường hợp.Player.getCurrentLiveOffsettrả về độ lệch giữa thời gian thực hiện tại và vị trí phát (nếu có).Player.getDurationtrả về độ dài của cửa sổ phát trực tiếp hiện tại.Player.getCurrentPositiontrả về vị trí phát tương ứng với thời điểm bắt đầu của cửa sổ phát trực tiếp.Player.getCurrentMediaItemtrả về mục nội dung nghe nhìn hiện tại, trong đóMediaItem.liveConfigurationchứa các chế độ ghi đè do ứng dụng cung cấp cho các tham số điều chỉnh độ lệch trực tiếp và độ lệch trực tiếp mục tiêu.Player.getCurrentTimelinetrả về cấu trúc nội dung nghe nhìn hiện tại trong mộtTimeline. Bạn có thể truy xuấtTimeline.Windowhiện tại từTimelinebằng cách sử dụngPlayer.getCurrentMediaItemIndexvàTimeline.getWindow. TrongWindow:Window.liveConfigurationchứa các tham số điều chỉnh độ lệch trực tiếp và độ lệch trực tiếp mục tiêu. Các giá trị này dựa trên thông tin trong nội dung nghe nhìn và mọi chế độ ghi đè do ứng dụng cung cấp được đặt trongMediaItem.liveConfiguration.Window.windowStartTimeMslà thời gian kể từ Thời gian bắt đầu của hệ thống Unix mà cửa sổ phát trực tiếp bắt đầu.Window.getCurrentUnixTimeMslà thời gian kể từ Thời gian bắt đầu của hệ thống Unix của thời gian thực hiện tại. Giá trị này có thể được điều chỉnh theo sự khác biệt đã biết về đồng hồ giữa máy chủ và ứng dụng.Window.getDefaultPositionMslà vị trí trong cửa sổ phát trực tiếp mà trình phát sẽ bắt đầu phát theo mặc định.
Tìm kiếm trong sự kiện phát trực tiếp
Bạn có thể tua đến bất kỳ vị trí nào trong cửa sổ phát trực tiếp bằng cách sử dụng biểu tượng Player.seekTo. Vị trí tìm kiếm được truyền tương ứng với thời điểm bắt đầu của cửa sổ phát trực tiếp. Ví dụ: seekTo(0) sẽ tua đến đầu cửa sổ phát trực tiếp. Sau khi bạn tua đến một vị trí, trình phát sẽ cố gắng giữ nguyên độ lệch phát trực tiếp như vị trí bạn tua đến.
Cửa sổ phát trực tiếp cũng có một vị trí mặc định mà tại đó quá trình phát dự kiến sẽ bắt đầu. Vị trí này thường nằm ở đâu đó gần cạnh trực tiếp. Bạn có thể tìm đến vị trí mặc định bằng cách gọi Player.seekToDefaultPosition.
Giao diện người dùng phát trực tiếp
Các thành phần giao diện người dùng mặc định của ExoPlayer cho biết thời lượng của cửa sổ phát trực tiếp và vị trí phát hiện tại trong cửa sổ đó. Điều này có nghĩa là vị trí sẽ xuất hiện để quay lại mỗi khi cửa sổ trực tiếp được cập nhật. Nếu cần hành vi khác, chẳng hạn như hiển thị thời gian Unix hoặc độ lệch trực tiếp hiện tại, bạn có thể phân nhánh PlayerControlView và sửa đổi để phù hợp với nhu cầu của mình.
Định cấu hình các thông số phát trực tiếp
ExoPlayer sử dụng một số tham số để kiểm soát độ lệch của vị trí phát so với cạnh trực tiếp và phạm vi tốc độ phát có thể dùng để điều chỉnh độ lệch này.
ExoPlayer nhận các giá trị cho những tham số này từ 3 vị trí, theo thứ tự ưu tiên giảm dần (giá trị đầu tiên tìm thấy sẽ được dùng):
- Mỗi giá trị
MediaItemđược truyền đếnMediaItem.Builder.setLiveConfiguration. - Giá trị mặc định chung được đặt trên
DefaultMediaSourceFactory. - Giá trị được đọc trực tiếp từ nội dung nghe nhìn.
Kotlin
// Global settings. val player = ExoPlayer.Builder(context) .setMediaSourceFactory(DefaultMediaSourceFactory(context).setLiveTargetOffsetMs(5000)) .build() // Per MediaItem settings. val mediaItem = MediaItem.Builder() .setUri(mediaUri) .setLiveConfiguration( MediaItem.LiveConfiguration.Builder().setMaxPlaybackSpeed(1.02f).build() ) .build() player.setMediaItem(mediaItem)
Java
// Global settings. ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setLiveTargetOffsetMs(5000)) .build(); // Per MediaItem settings. MediaItem mediaItem = new MediaItem.Builder() .setUri(mediaUri) .setLiveConfiguration( new MediaItem.LiveConfiguration.Builder().setMaxPlaybackSpeed(1.02f).build()) .build(); player.setMediaItem(mediaItem);
Các giá trị cấu hình có thể sử dụng là:
targetOffsetMs: Độ lệch phát trực tiếp mục tiêu. Nếu có thể, trình phát sẽ cố gắng phát ở gần khoảng thời gian phát trực tiếp này.minOffsetMs: Mức chênh lệch tối thiểu được phép cho video phát trực tiếp. Ngay cả khi điều chỉnh độ lệch theo điều kiện mạng hiện tại, trình phát sẽ không cố gắng giảm xuống dưới độ lệch này trong quá trình phát.maxOffsetMs: Mức chênh lệch tối đa được phép khi phát trực tiếp. Ngay cả khi điều chỉnh độ trễ theo điều kiện mạng hiện tại, trình phát sẽ không cố gắng vượt quá độ trễ này trong quá trình phát.minPlaybackSpeed: Tốc độ phát tối thiểu mà trình phát có thể dùng để quay lại khi cố gắng đạt được độ lệch trực tiếp mục tiêu.maxPlaybackSpeed: Tốc độ phát tối đa mà trình phát có thể sử dụng để bắt kịp khi cố gắng đạt được độ lệch trực tiếp mục tiêu.
Điều chỉnh tốc độ phát
Khi phát một sự kiện phát trực tiếp có độ trễ thấp, ExoPlayer sẽ điều chỉnh độ lệch trực tiếp bằng cách thay đổi nhẹ tốc độ phát. Trình phát sẽ cố gắng so khớp với độ lệch phát trực tiếp mục tiêu do nội dung nghe nhìn hoặc ứng dụng cung cấp, nhưng cũng sẽ cố gắng phản ứng với các điều kiện mạng thay đổi. Ví dụ: nếu xảy ra hiện tượng tải lại bộ nhớ đệm trong quá trình phát, thì trình phát sẽ giảm tốc độ phát một chút để tránh xa hơn so với cạnh trực tiếp. Nếu mạng đủ ổn định để hỗ trợ phát gần với thời điểm phát trực tiếp (live edge) một lần nữa, thì trình phát sẽ tăng tốc độ phát để quay lại mức chênh lệch phát trực tiếp mục tiêu.
Nếu không muốn tự động điều chỉnh tốc độ phát, bạn có thể tắt tính năng này bằng cách đặt các thuộc tính minPlaybackSpeed và maxPlaybackSpeed thành 1.0f.
Tương tự, bạn có thể bật chế độ này cho các sự kiện phát trực tiếp không có độ trễ thấp bằng cách đặt rõ ràng các giá trị này thành các giá trị khác 1.0f. Hãy xem phần cấu hình ở trên để biết thêm thông tin chi tiết về cách thiết lập các thuộc tính này.
Tuỳ chỉnh thuật toán điều chỉnh tốc độ phát
Nếu bạn bật chế độ điều chỉnh tốc độ, thì LivePlaybackSpeedControl sẽ xác định những điều chỉnh được thực hiện. Bạn có thể triển khai LivePlaybackSpeedControl tuỳ chỉnh hoặc tuỳ chỉnh quy trình triển khai mặc định là DefaultLivePlaybackSpeedControl. Trong cả hai trường hợp, bạn có thể đặt một thực thể khi tạo trình phát:
Kotlin
val player = ExoPlayer.Builder(context) .setLivePlaybackSpeedControl( DefaultLivePlaybackSpeedControl.Builder().setFallbackMaxPlaybackSpeed(1.04f).build() ) .build()
Java
ExoPlayer player = new ExoPlayer.Builder(context) .setLivePlaybackSpeedControl( new DefaultLivePlaybackSpeedControl.Builder() .setFallbackMaxPlaybackSpeed(1.04f) .build()) .build();
Các thông số tuỳ chỉnh có liên quan của DefaultLivePlaybackSpeedControl là:
fallbackMinPlaybackSpeedvàfallbackMaxPlaybackSpeed: Tốc độ phát tối thiểu và tối đa có thể dùng để điều chỉnh nếu cả nội dung nghe nhìn vàMediaItemdo ứng dụng cung cấp đều không xác định giới hạn.proportionalControlFactor: Kiểm soát độ mượt của việc điều chỉnh tốc độ. Giá trị cao sẽ khiến các điều chỉnh diễn ra đột ngột và phản ứng nhanh hơn, nhưng cũng có nhiều khả năng nghe thấy hơn. Giá trị càng nhỏ, quá trình chuyển đổi giữa các tốc độ càng mượt mà, nhưng tốc độ sẽ chậm hơn.targetLiveOffsetIncrementOnRebufferMs: Giá trị này được thêm vào độ lệch phát trực tiếp mục tiêu bất cứ khi nào xảy ra hiện tượng đệm lại, để tiếp tục một cách thận trọng hơn. Bạn có thể tắt tính năng này bằng cách đặt giá trị thành 0.minPossibleLiveOffsetSmoothingFactor: Hệ số làm mịn theo hàm mũ dùng để theo dõi độ lệch phát trực tiếp tối thiểu có thể dựa trên nội dung nghe nhìn hiện được lưu vào bộ nhớ đệm. Giá trị rất gần với 1 có nghĩa là thông tin ước tính thận trọng hơn và có thể mất nhiều thời gian hơn để điều chỉnh theo điều kiện mạng được cải thiện, trong khi giá trị thấp hơn có nghĩa là thông tin ước tính sẽ điều chỉnh nhanh hơn với nguy cơ gặp phải tình trạng đệm lại cao hơn.
BehindLiveWindowException và ERROR_CODE_BEHIND_LIVE_WINDOW
Vị trí phát có thể bị trễ so với cửa sổ phát trực tiếp, chẳng hạn như nếu trình phát bị tạm dừng hoặc đang đệm trong một khoảng thời gian đủ dài. Nếu điều này xảy ra, quá trình phát sẽ không thành công và một ngoại lệ có mã lỗi ERROR_CODE_BEHIND_LIVE_WINDOW sẽ được báo cáo thông qua Player.Listener.onPlayerError. Mã ứng dụng có thể muốn xử lý những lỗi như vậy bằng cách tiếp tục phát ở vị trí mặc định. PlayerActivity của ứng dụng minh hoạ minh hoạ phương pháp này.
Kotlin
override fun onPlayerError(error: PlaybackException) { if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) { // Re-initialize player at the live edge. player.seekToDefaultPosition() player.prepare() } else { // Handle other errors } }
Java
@Override public void onPlayerError(PlaybackException error) { if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) { // Re-initialize player at the live edge. player.seekToDefaultPosition(); player.prepare(); } else { // Handle other errors } }