Tin tức về sản phẩm

Media3 1.9.0 – Tính năng mới

Đọc trong 6 phút
Kristina Simakova
Quản lý kỹ thuật

Media3 1.9.0 đã ra mắt! Ngoài các bản sửa lỗi thông thường và cải thiện hiệu suất, bản phát hành mới nhất này còn chứa 4 mô-đun mới hoặc được viết lại phần lớn:

  • media3-inspector – Trích xuất siêu dữ liệu và khung hình bên ngoài quá trình phát
  • media3-ui-compose-material3 – Xây dựng giao diện người dùng cơ bản cho nội dung nghe nhìn bằng Compose Material3 chỉ trong vài bước
  • media3-cast – Tự động xử lý quá trình chuyển đổi giữa quá trình phát trên Cast và quá trình phát cục bộ
  • media3-decoder-av1 – Phát AV1 nhất quán bằng bộ giải mã phần mở rộng được viết lại dựa trên thư viện dav1d

Chúng tôi cũng đã cải thiện tính năng quản lý bộ nhớ và bộ nhớ đệm cho PreloadManager, đồng thời đơn giản hoá một số ExoPlayerTransformerMediaSession mới. 

Bản phát hành này cũng cho phép bạn truy cập thử nghiệm lần đầu vào CompositionPlayer để xem trước các chỉnh sửa nội dung nghe nhìn.  


Hãy đọc tiếp để tìm hiểu thêm. Như thường lệ, vui lòng xem ghi chú phát hành đầy đủ để biết thông tin tổng quan toàn diện về các thay đổi trong bản phát hành này.

Trích xuất siêu dữ liệu và khung hình bên ngoài quá trình phát

Có nhiều trường hợp bạn muốn kiểm tra nội dung nghe nhìn mà không cần bắt đầu phát. Ví dụ: bạn có thể muốn phát hiện định dạng của nội dung nghe nhìn hoặc thời lượng của nội dung nghe nhìn đó, hoặc truy xuất hình thu nhỏ.

Mô-đun media3-inspector mới kết hợp tất cả các tiện ích để kiểm tra nội dung nghe nhìn mà không cần phát ở một nơi:

  • MetadataRetriever để đọc thời lượng, định dạng và siêu dữ liệu tĩnh từ MediaItem.
  • FrameExtractor để lấy khung hình hoặc hình thu nhỏ từ một mục.
  • MediaExtractorCompat để thay thế trực tiếp cho lớp MediaExtractor của nền tảng Android, nhằm lấy thông tin chi tiết về các mẫu trong tệp.

MetadataRetrieverFrameExtractor tuân theo mẫu AutoCloseable đơn giản. Hãy xem các trang hướng dẫn mới của chúng tôi để biết thêm thông tin chi tiết.

  suspend fun extractThumbnail(mediaItem: MediaItem) {

  FrameExtractor.Builder(context, mediaItem).build().use {

    val thumbnail = frameExtractor.getThumbnail().await()

  } 

}

Xây dựng giao diện người dùng cơ bản cho nội dung nghe nhìn bằng Compose Material3 chỉ trong vài bước

Trong các bản phát hành trước, chúng tôi đã bắt đầu cung cấp mã trình kết nối giữa các thành phần giao diện người dùng Compose và thực thể Trình phát. Với Media3 1.9.0, chúng tôi đã thêm một mô-đun mới là media3-ui-compose-material3 với các nút và thành phần nội dung Material3 được tạo kiểu đầy đủ. Các thành phần này cho phép bạn xây dựng giao diện người dùng cho nội dung nghe nhìn chỉ trong vài bước, đồng thời cung cấp mọi sự linh hoạt để tuỳ chỉnh kiểu. Nếu muốn xây dựng kiểu giao diện người dùng của riêng mình, bạn có thể sử dụng các khối xây dựng giúp xử lý tất cả logic cập nhật và kết nối, nhờ đó, bạn chỉ cần tập trung vào việc thiết kế phần tử trên giao diện người dùng. Vui lòng xem các trang hướng dẫn mở rộng của chúng tôi về các mô-đun giao diện người dùng Compose.

Chúng tôi cũng đang tiếp tục phát triển thêm nhiều thành phần Compose, chẳng hạn như thanh tìm kiếm được tạo sẵn, một thành phần thay thế hoàn chỉnh, có sẵn cho PlayerView, cũng như tính năng tích hợp phụ đề và quảng cáo.

  @Composable
fun SimplePlayerUI(player: Player, modifier: Modifier = Modifier) {
  Column(modifier) {
    ContentFrame(player)  // Video surface and shutter logic
    Row (Modifier.align(Alignment.CenterHorizontally)) {                 
      SeekBackButton(player)   // Simple controls
      PlayPauseButton(player)
      SeekForwardButton(player)
    }
  }
}

 

image.png

Giao diện người dùng trình phát Compose đơn giản với các thành phần có sẵn

Tự động xử lý quá trình chuyển đổi giữa quá trình phát trên Cast và quá trình phát cục bộ

CastPlayer trong mô-đun media3-cast đã được viết lại để tự động xử lý quá trình chuyển đổi giữa quá trình phát cục bộ (ví dụ: bằng ExoPlayer) và quá trình phát Cast từ xa.

Khi thiết lập MediaSession, bạn chỉ cần xây dựng CastPlayer xung quanh ExoPlayer và thêm MediaRouteButton vào giao diện người dùng là xong!

  // MediaSession setup with CastPlayer 

val exoPlayer = ExoPlayer.Builder(context).build()

val castPlayer = CastPlayer.Builder(context).setLocalPlayer(exoPlayer).build()

val session = MediaSession.Builder(context, castPlayer).build()

// MediaRouteButton in UI 

@Composable fun UIWithMediaRouteButton() {

  MediaRouteButton()

}
image.png

Tính năng tích hợp CastPlayer mới trong ứng dụng minh họa phiên Media3

Phát AV1 nhất quán bằng phần mở rộng được viết lại dựa trên dav1d

Bản phát hành 1.9.0 chứa một mô-đun phần mở rộng AV1 được viết lại hoàn toàn dựa trên thư viện dav1d phổ biến. 

Giống như tất cả các mô-đun bộ giải mã phần mở rộng, xin lưu ý rằng bạn cần phải xây dựng từ nguồn  để gói mã gốc có liên quan một cách chính xác. Việc gói bộ giải mã giúp đảm bảo tính nhất quán và hỗ trợ định dạng trên tất cả các thiết bị, nhưng vì quá trình giải mã chạy trong quy trình của bạn nên tính năng này phù hợp nhất với nội dung mà bạn có thể tin tưởng. 

Tích hợp tính năng quản lý bộ nhớ và bộ nhớ đệm vào PreloadManager

Chúng tôi cũng đã cải thiện PreloadManager. Tính năng này đã cho phép bạn tải trước nội dung nghe nhìn vào bộ nhớ bên ngoài quá trình phát, sau đó chuyển liền mạch cho trình phát khi cần. Mặc dù có hiệu suất khá cao, nhưng bạn vẫn phải cẩn thận để không vượt quá giới hạn bộ nhớ bằng cách vô tình tải trước quá nhiều. Vì vậy, với Media3 1.9.0, chúng tôi đã thêm 2 tính năng giúp quá trình này trở nên dễ dàng và ổn định hơn nhiều:

  1. Hỗ trợ bộ nhớ đệm – Khi xác định mức độ tải trước, giờ đây, bạn có thể chọn PreloadStatus.specifiedRangeCached(0, 5000) làm trạng thái mục tiêu cho các mục được tải trước. Thao tác này sẽ thêm phạm vi đã chỉ định vào bộ nhớ đệm trên ổ đĩa thay vì tải dữ liệu vào bộ nhớ. Nhờ đó, bạn có thể cung cấp một phạm vi mục lớn hơn nhiều để tải trước vì các mục ở xa mục hiện tại không cần chiếm bộ nhớ nữa. Xin lưu ý rằng bạn cần phải đặt Cache trong DefaultPreloadManager.Builder.
  2. Tự động quản lý bộ nhớ – Chúng tôi cũng đã cập nhật giao diện LoadControl để xử lý tốt hơn trường hợp tải trước, nhờ đó, giờ đây, bạn có thể đặt giới hạn bộ nhớ trên một cách rõ ràng cho tất cả các mục được tải trước trong bộ nhớ. Theo mặc định, giới hạn này là 144 MB và bạn có thể định cấu hình giới hạn này trong DefaultLoadControl.Builder. DefaultPreloadManager sẽ tự động ngừng tải trước khi đạt đến giới hạn và tự động giải phóng bộ nhớ của các mục có mức độ ưu tiên thấp hơn nếu cần.

Dựa vào các hành vi mặc định mới được đơn giản hoá trong ExoPlayer

Như thường lệ, chúng tôi cũng đã bổ sung nhiều điểm cải tiến gia tăng cho ExoPlayer. Sau đây chỉ là một vài điểm cải tiến:

  • Tắt tiếng và bật tiếng – Chúng tôi đã có phương thức setVolume, nhưng giờ đây đã thêm các phương thức tiện lợi muteunmute để dễ dàng khôi phục âm lượng trước đó mà không cần tự theo dõi.
  • Phát hiện trình phát bị kẹt – Trong một số trường hợp hiếm gặp, trình phát có thể bị kẹt ở trạng thái đệm hoặc phát mà không có tiến triển nào, ví dụ: do sự cố codec hoặc cấu hình sai. Người dùng sẽ cảm thấy khó chịu, nhưng bạn không bao giờ thấy những vấn đề này trong dữ liệu phân tích của mình! Để làm cho vấn đề này rõ ràng hơn, trình phát hiện báo cáo StuckPlayerException khi phát hiện trạng thái bị kẹt.
  • Khoá chế độ thức theo mặc định – Trước đây, tính năng quản lý khoá chế độ thức là tính năng chọn tham gia, dẫn đến các trường hợp khó tìm thấy khi tiến trình phát có thể bị trì hoãn rất nhiều khi chạy ở chế độ nền. Giờ đây, tính năng này là tính năng chọn không tham gia, vì vậy, bạn không phải lo lắng về tính năng này và cũng có thể xoá tất cả hoạt động xử lý khoá chế độ thức thủ công xung quanh quá trình phát.
  • Cài đặt đơn giản cho logic nút CC – Việc thay đổi TrackSelectionParameters để nói "bật/tắt phụ đề" rất khó thực hiện đúng cách, vì vậy, chúng tôi đã thêm một tuỳ chọn boolean đơn giản selectTextByDefault cho trường hợp sử dụng này.

Đơn giản hoá lựa chọn ưu tiên cho nút nội dung nghe nhìn trong MediaSession

Cho đến nay, việc xác định lựa chọn ưu tiên cho các nút sẽ xuất hiện trong ngăn thông báo nội dung nghe nhìn trên Android Auto hoặc WearOS đòi hỏi phải xác định các nút và lệnh tuỳ chỉnh, ngay cả khi bạn chỉ muốn kích hoạt một phương thức trình phát tiêu chuẩn.

Media3 1.9.0 có chức năng mới giúp quá trình này trở nên đơn giản hơn nhiều – giờ đây, bạn có thể xác định lựa chọn ưu tiên cho nút nội dung nghe nhìn bằng một lệnh trình phát tiêu chuẩn mà không cần xử lý lệnh tuỳ chỉnh.

  session.setMediaButtonPreferences(listOf(
    CommandButton.Builder(CommandButton.ICON_FAST_FORWARD) // choose an icon
      .setDisplayName(R.string.skip_forward)
      .setPlayerCommand(Player.COMMAND_SEEK_FORWARD) // choose an action 
      .build()
))
image.png

Lựa chọn ưu tiên cho nút nội dung nghe nhìn với nút tua nhanh

CompositionPlayer để xem trước theo thời gian thực

Bản phát hành 1.9.0 giới thiệu CompositionPlayer theo chú thích @ExperimentalApi mới. Chú thích này cho biết rằng tính năng này có thể dùng để thử nghiệm, nhưng vẫn đang trong quá trình phát triển. 

CompositionPlayer là một thành phần mới trong API chỉnh sửa Media3 được thiết kế để xem trước các chỉnh sửa nội dung nghe nhìn theo thời gian thực. Được xây dựng dựa trên giao diện Media3 Player quen thuộc, CompositionPlayer cho phép người dùng xem các thay đổi của họ trong quá trình thực hiện trước khi cam kết với quy trình xuất. Tính năng này sử dụng cùng một đối tượng Composition mà bạn sẽ chuyển đến Transformer để xuất, giúp đơn giản hoá quy trình chỉnh sửa bằng cách hợp nhất mô hình dữ liệu để xem trước và xuất.

Chúng tôi khuyến khích bạn bắt đầu sử dụng CompositionPlayer và chia sẻ ý kiến phản hồi, đồng thời theo dõi các bài đăng và bản cập nhật sắp tới cho tài liệu để biết thêm thông tin chi tiết.

InAppMuxer làm bộ ghép kênh mặc định trong Transformer

Giờ đây, Transformer sử dụng InAppMp4Muxer làm bộ ghép kênh mặc định để ghi các tệp vùng chứa nội dung nghe nhìn. Về nội bộ, InAppMp4Muxer phụ thuộc vào mô-đun Media3 Muxer, mang lại hành vi nhất quán trên tất cả các phiên bản API. 

Xin lưu ý rằng mặc dù Transformer không còn sử dụng MediaMuxer của Nền tảng Android theo mặc định, nhưng bạn vẫn có thể cung cấp FrameworkMuxer.Factory thông qua setMuxerFactory nếu trường hợp sử dụng của bạn yêu cầu.

API điều chỉnh tốc độ mới

Bản phát hành 1.9.0 đơn giản hoá API điều chỉnh tốc độ để chỉnh sửa nội dung nghe nhìn. Chúng tôi đã giới thiệu các phương thức mới trực tiếp trên EditedMediaItem.Builder để kiểm soát tốc độ, giúp API trở nên trực quan hơn. Giờ đây, bạn có thể thay đổi tốc độ của một đoạn video bằng cách gọi setSpeed(SpeedProvider provider) trên EditedMediaItem.Builder:

  val speedProvider = object : SpeedProvider {
    override fun getSpeed(presentationTimeUs: Long): Float {
        return speed
    }

    override fun getNextSpeedChangeTimeUs(timeUs: Long): Long {
        return C.TIME_UNSET
    }
}

EditedMediaItem speedEffectItem = EditedMediaItem.Builder(mediaItem)
    .setSpeed(speedProvider)
    .build()

Phương pháp mới này thay thế phương thức trước đó là sử dụng Effects#createExperimentalSpeedChangingEffects(), phương thức này không còn được dùng nữa và sẽ bị xoá trong một bản phát hành sau này.

Giới thiệu các loại bản nhạc cho EditedMediaItemSequence

Trong bản phát hành 1.9.0, EditedMediaItemSequence yêu cầu chỉ định các loại bản nhạc đầu ra mong muốn trong quá trình tạo chuỗi. Thay đổi này đảm bảo việc xử lý bản nhạc rõ ràng và mạnh mẽ hơn trên toàn bộ Thành phần. 

Bạn có thể thực hiện việc này thông qua một hàm khởi tạo EditedMediaItemSequence.Builder mới chấp nhận một tập hợp các loại bản nhạc (ví dụ: C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO).

Để đơn giản hoá quá trình tạo, chúng tôi đã thêm các phương thức tiện lợi tĩnh mới:

  • EditedMediaItemSequence.withAudioFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withVideoFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withAudioAndVideoFrom(List<EditedMediaItem>)

Bạn nên di chuyển sang hàm khởi tạo mới hoặc các phương thức tiện lợi để có định nghĩa chuỗi rõ ràng và đáng tin cậy hơn.

Ví dụ về cách tạo chuỗi chỉ có video:

  EditedMediaItemSequence videoOnlySequence =
    EditedMediaItemSequence.Builder(setOf(C.TRACK_TYPE_VIDEO))
        .addItem(editedMediaItem)
        .build()

Vui lòng liên hệ thông qua Trình theo dõi lỗi Media3 nếu bạn gặp phải bất kỳ lỗi nào hoặc nếu bạn có câu hỏi hoặc yêu cầu về tính năng. Chúng tôi rất mong nhận được ý kiến của bạn!

Tác giả:

Tiếp tục đọc