ExoPlayer phát hầu hết các luồng phát trực tiếp thích ứng ngay từ đầu 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ổ nội dung nghe nhìn có sẵn đượ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 ở đâu đó trong cửa sổ này, trong hầu hết các trường hợp, gần với thời gian thực hiện tại mà luồng đang được tạo. Sự khác biệt giữa thời gian thực hiện tại và vị trí phát được gọi là độ lệch trực tiếp.
Phát hiện và giám sát chế độ phát trực tiếp
Mỗi khi một 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ề quá trình 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à hiển thị trong hình sau.
Player.isCurrentWindowLive
cho 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.isCurrentWindowDynamic
cho biết liệu mục nội dung nghe nhìn đang phát có vẫn đang được cập nhật hay không. Điều này thường đúng với các 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 áp dụng cho các sự kiện phát trực tiếp không phải sự kiện phát trực tiếp trong một số trường hợp.Player.getCurrentLiveOffset
trả về độ lệch giữa thời gian thực hiện tại và vị trí phát (nếu có).Player.getDuration
trả về độ dài của cửa sổ hiện tại đang hoạt động.Player.getCurrentPosition
trả về vị trí phát tương ứng với vị trí bắt đầu của cửa sổ phát trực tiếp.Player.getCurrentMediaItem
trả về mục nội dung đa phương tiện hiện tại, trong đóMediaItem.liveConfiguration
chứa các chế độ ghi đè do ứng dụng cung cấp đối với các tham số điều chỉnh độ lệch trực tiếp mục tiêu và điều chỉnh chênh lệch trực tiếp.Player.getCurrentTimeline
trả về cấu trúc nội dung đa phương tiện hiện tại trongTimeline
. Bạn có thể truy xuấtTimeline.Window
hiện tại từTimeline
bằng cách sử dụngPlayer.getCurrentMediaItemIndex
vàTimeline.getWindow
. TrongWindow
:Window.liveConfiguration
chứ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 giá trị ghi đè do ứng dụng cung cấp được đặt trongMediaItem.liveConfiguration
.Window.windowStartTimeMs
là thời gian kể từ thời gian bắt đầu của hệ thống Unix mà cửa sổ trực tiếp bắt đầu.Window.getCurrentUnixTimeMs
là 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 bằng độ lệch đồng hồ đã biết giữa máy chủ và ứng dụng khách.Window.getDefaultPositionMs
là 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 vị trí bất kỳ trong cửa sổ phát trực tiếp bằng Player.seekTo
. Vị trí tìm kiếm đã truyền tương ứng với thời điểm bắt đầu cửa sổ trực tiếp. Ví dụ: seekTo(0)
sẽ tìm cách bắt đầu cửa sổ trực tiếp. Trình phát sẽ cố gắng giữ nguyên độ lệch trực tiếp như vị trí đã tua đến sau khi tua.
Cửa sổ phát trực tiếp cũng có vị trí mặc định mà tại đó quá trình phát sẽ bắt đầu. Vị trí này thường nằm gần cạnh sống. 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ẽ có vẻ như nhảy 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ố thông số để kiểm soát độ lệch của vị trí phát từ cạnh phát 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 lấy giá trị cho các tham số này từ 3 vị trí, theo thứ tự ưu tiên giảm dần (giá trị đầu tiên được tìm thấy sẽ được sử dụng):
- Trên mỗi
MediaItem
giá trị đượ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 hiện có là:
targetOffsetMs
: Độ lệch trực tiếp mục tiêu. Trình phát sẽ cố gắng đạt được độ lệch trực tiếp này trong khi phát nếu có thể.minOffsetMs
: Độ lệch trực tiếp tối thiểu được phé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 giảm xuống dưới độ trễ này trong khi phát.maxOffsetMs
: Độ lệch trực tiếp tối đa được phé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 vượt quá độ lệch này trong khi phát.minPlaybackSpeed
: Tốc độ phát tối thiểu mà trình phát có thể sử dụng để quay lại khi cố gắng đạt đến độ 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 độ trễ phát trực tiếp mục tiêu.
Điều chỉnh tốc độ phát
Khi phát sự kiện phát trực tiếp có độ trễ thấp, ExoPlayer sẽ điều chỉnh độ trễ phát trực tiếp bằng cách thay đổi một chút tốc độ phát. Trình phát sẽ cố gắng khớp độ lệch 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 tình trạng vùng đệm lại trong khi phát, thì trình phát sẽ giảm tốc độ phát một chút để di chuyển ra xa cạnh trực tiếp (phát trực tiếp). Nếu sau đó mạng trở nên đủ ổn định để hỗ trợ việc phát lại gần hơn phiên bản phát trực tiếp, trình phát sẽ tăng tốc độ phát để quay lại độ lệch 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 thuộc tính minPlaybackSpeed
và maxPlaybackSpeed
thành 1.0f
.
Tương tự, bạn có thể bật tính năng 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 các giá trị này thành các giá trị khác với 1.0f
. Vui lòng xem phần cấu hình ở trên để biết thêm thông tin chi tiết về cách đặt 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 tính năng điều chỉnh tốc độ, LivePlaybackSpeedControl
sẽ xác định những điều chỉnh được thực hiện. Bạn có thể triển khai một LivePlaybackSpeedControl
tuỳ chỉnh hoặc tuỳ chỉnh cách 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à:
fallbackMinPlaybackSpeed
và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 hoặcMediaItem
do ứng dụng cung cấp đều không xác định giới hạn.proportionalControlFactor
: Kiểm soát độ mượt mà của việc điều chỉnh tốc độ. Giá trị cao sẽ giúp việc điều chỉnh trở nên đột ngột và phản ứng nhanh hơn, nhưng cũng có nhiều khả năng sẽ nghe được. Giá trị nhỏ hơn sẽ giúp quá trình chuyển đổi giữa các tốc độ diễn ra mượt mà hơn, nhưng tốc độ sẽ chậm hơn.targetLiveOffsetIncrementOnRebufferMs
: Giá trị này được thêm vào độ lệch trực tiếp mục tiêu bất cứ khi nào xảy ra tình trạng phải tải lại để tiến hành 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ượt mũ được dùng để theo dõi độ lệch trực tiếp tối thiểu có thể có dựa trên nội dung nghe nhìn hiện đang được lưu vào vùng đệm. Giá trị rất gần với 1 có nghĩa là giá trị ước tính sẽ thận trọng hơn và có thể mất nhiều thời gian hơn để điều chỉnh theo tình trạng mạng được cải thiện, trong khi giá trị thấp hơn có nghĩa là giá trị ước tính sẽ điều chỉnh nhanh hơn với nguy cơ cao hơn là phải lưu vào bộ đệm lại.
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, ví dụ: nếu trình phát bị tạm dừng hoặc lưu vào bộ nhớ đệ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 qua Player.Listener.onPlayerError
. Mã ứng dụng có thể xử lý các 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 } }