Phát trực tiếp

ExoPlayer phát ngay hầu hết các sự kiện phát trực tiếp thích ứng mà không cần bất kỳ . 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 trong đều đặn để di chuyển theo thời gian thực hiện tại. Tức là lượt phát vị trí sẽ luôn ở đâ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 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 lượt phát trực tiếp

Mỗi khi một cửa sổ trực tiếp được cập nhật, đã đăng ký thực thể Player.Listener 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 đang diễn ra bằng cách truy vấn các PlayerTimeline.Window khác nhau như được liệt kê dưới đây và thể hiện trong hình bên dưới.

Cửa sổ trực tiếp

  • Player.isCurrentWindowLive cho biết nội dung nghe nhìn hiện đang phát có mặt hàng là một sự kiện phát trực tiếp. 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 nội dung nghe nhìn hiện đang phát có mục này vẫn đang được cập nhật. Đ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. Lưu ý rằng cờ này cũng đúng với các luồng không phải là sự kiện phát trực tiếp ở một số trường hợp.
  • Player.getCurrentLiveOffset trả về độ lệch giữa giá trị 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 đầu cửa sổ 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ơ chế ghi đè do ứng dụng cung cấp cho mục tiêu các thông số điều chỉnh bù trừ trực tiếp và bù trừ trực tiếp.
  • Player.getCurrentTimeline trả về cấu trúc đa phương tiện hiện tại trong một Timeline Bạn có thể truy xuất Timeline.Window hiện tại từ Timeline thông qua Player.getCurrentWindowIndexTimeline.getWindow. Trong Window:
    • Window.liveConfiguration chứa độ lệch trực tiếp mục tiêu và độ lệch trực tiếp tham số điều chỉnh. 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 trong MediaItem.liveConfiguration.
    • Window.windowStartTimeMs là thời gian kể từ Kỷ nguyên Unix mà tại đó cửa sổ trực tiếp sẽ bắt đầu.
    • Window.getCurrentUnixTimeMs là thời điểm kể từ Kỷ nguyên Unix của thời gian thực hiện tại. Giá trị này có thể được sửa nếu có sự chênh lệch về đồng hồ đã biết giữa máy chủ và ứng dụng.
    • Window.getDefaultPositionMs là vị trí trong cửa sổ trực tiếp mà tại đó thì theo mặc định, trình phát sẽ bắt đầu phát.

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ổ trực tiếp bằng Player.seekTo. Tìm kiếm vị trí được 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. Người chơi sẽ cố gắng giữ nguyên vị trí tua trực tiếp sau khi tua.

Cửa sổ trực tiếp cũng có một vị trí mặc định mà tại đó chế độ phát đầu. Vị trí này thường nằm ở đâu đó gần cạnh cạnh phiên bản trực tiếp. Bạn có thể tìm kiếm vị trí mặc định bằng cách gọi Player.seekToDefaultPosition.

Giao diện người dùng của tính nă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 thấy thời lượng của cửa sổ trực tiếp và vị trí phát hiện tại bên trong đó. Điều này có nghĩa là vị trí sẽ xuất hiện lùi lại mỗi khi cửa sổ trực tiếp được cập nhật. Nếu bạn cần ví dụ: hiển thị thời gian Unix hoặc giá trị bù trừ trực tiếp hiện tại, bạn có thể phát triển nhánh PlayerControlView và sửa đổi cho phù hợp với nhu cầu của bạn.

Định cấu hình các tham số phát trực tiếp

ExoPlayer sử dụng một số tham số để điều khiển độ lệch của vị trí phát từ rìa 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 nhận giá trị cho các tham số này từ 3 vị trí, theo thứ tự giảm dần thứ tự ưu tiên (giá trị đầu tiên tìm thấy là giá trị):

  • Trên mỗi MediaItem giá trị được truyền đến MediaItem.Builder.setLiveConfiguration.
  • Giá trị mặc định chung được đặt vào DefaultMediaSourceFactory.
  • Các 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ó sẵn là:

  • targetOffsetMs: Độ lệch trực tiếp mục tiêu. Người chơi sẽ cố gắng lấy gần với độ 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 bạn điều chỉnh bù với điều kiện mạng hiện tại, trình phát sẽ không cố gắng xuống dưới độ lệch này trong khi phát.
  • maxOffsetMs: Độ lệch trực tiếp tối đa được phép. Ngay cả khi bạn điều chỉnh bù với điều kiện mạng hiện tại, người chơi sẽ không cố gắng đạt được độ lệch này trong khi phát.
  • minPlaybackSpeed: Tốc độ phát tối thiểu mà người chơi 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à người chơi có thể sử dụng để bắt kịp khi cố gắng đạt đến độ 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 của sự kiện phát trực tiếp bằng cách thay đổi một chút tốc độ phát. Người chơi sẽ cố gắng khớp mục tiêu bù trừ trực tiếp do phương tiện truyền thông hoặc ứng dụng cung cấp, nhưng cũng sẽ cố gắng phản ứng với điều kiện mạng thay đổi. Ví dụ: nếu tình trạng đệm lại xảy ra trong khi phát, trình phát sẽ giảm tốc độ phát một chút để di chuyển ra xa khỏi nội dung phát trực tiếp cạnh. Nếu mạng trở nên đủ ổn định để hỗ trợ việc chơi ở gần cạnh tranh trực tiếp, trình phát sẽ tăng tốc độ phát để quay lại bù trừ trực tiếp mục tiêu.

Nếu không muốn điều chỉnh tốc độ phát tự động, bạn có thể tắt tính năng này bằng cách đặt các thuộc tính minPlaybackSpeedmaxPlaybackSpeed thành 1.0f. Tương tự, bạn có thể bật tính năng này cho sự kiện phát trực tiếp không có độ trễ thấp bằng cách thiết lập một cách rõ ràng cho các giá trị không phải là 1.0f. Xem phần cấu hình ở trên cho 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 các điều chỉnh được thực hiện. Có thể triển khai một bộ lọc tuỳ chỉnh LivePlaybackSpeedControl hoặc để tuỳ chỉnh cách triển khai mặc định, tức là DefaultLivePlaybackSpeedControl Trong cả hai trường hợp, bạn có thể đặt một thực thể khi xây dựng 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 tham số tuỳ chỉnh liên quan của DefaultLivePlaybackSpeedControl là:

  • fallbackMinPlaybackSpeedfallbackMaxPlaybackSpeed: Giá trị tối thiểu và tốc độ phát tối đa có thể dùng để điều chỉnh nếu cả phương tiện cũng như MediaItem do ứng dụng cung cấp 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 độ. Đáp giá trị cao làm cho điều chỉnh đột ngột và mang tính phản ứng hơn, nhưng cũng có nhiều khả năng có thể nghe được. Giá trị nhỏ hơn giúp việc chuyển đổi giữa các tốc độ diễn ra suôn sẻ hơn. nhưng sẽ chậm hơn.
  • targetLiveOffsetIncrementOnRebufferMs: Giá trị này sẽ được thêm vào mục tiêu bù trừ trực tiếp bất cứ khi nào xảy ra vùng đệm lại để tiến hành 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ượt theo cấp số nhân được dùng để theo dõi bù trừ trực tiếp tối thiểu có thể có dựa trên được lưu vào vùng đệm. Giá trị rất gần bằng 1 có nghĩa là giá trị ước tính cao hơn thận trọng 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à ước tính sẽ điều chỉnh nhanh hơn với rủi ro cao hơn gặp phải các bộ đệm lại.

BehindLiveWindowException và ERROR_CODE_BEHIND_LIVE_WINDOW

Vị trí phát có thể nằm phía sau 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 lưu vào bộ đệm trong khoảng thời gian đủ dài. Nếu trường hợp này xảy ra thì phát lại sẽ không thành công và một ngoại lệ với mã lỗi ERROR_CODE_BEHIND_LIVE_WINDOW sẽ được báo cáo qua Player.Listener.onPlayerError Mã xử lý ứng dụng có thể cần xử lý những vấn đề 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ạ để thể hiện 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
  }
}