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 và cải thiện hiệu suất thường thấy, bản phát hành mới nhất còn có 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 Material 3 chỉ trong vài bước
  • media3-cast – Tự động xử lý quá trình chuyển đổi giữa tính năng Truyền và phát cục bộ
  • media3-decoder-av1 – Phát nội dung AV1 nhất quán bằng bộ giải mã tiện ích được viết lại dựa trên thư viện dav1d

Chúng tôi cũng đã cải thiện khả năng lưu vào bộ nhớ đệm và quản lý bộ nhớ 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 dùng thử CompositionPlayer lần đầu tiên để xem trước nội dung chỉnh sửa đa phương tiện.  


Hãy đọc tiếp để tìm hiểu thêm và như thường lệ, vui lòng xem toàn bộ ghi chú phát hành để biết thông tin tổng quan toàn diện về những 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 tệp hoặc thời lượng của tệp, 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ỏ của một mục.
  • MediaExtractorCompat để thay thế trực tiếp cho lớp MediaExtractor của nền tảng Android, nhằm nhận thông tin chi tiết về các mẫu trong tệp.

MetadataRetriever và FrameExtractor tuân theo một 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 Material 3 Compose 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 phần tử giao diện người dùng Compose và phiên bản Trình phát của bạn. Với Media3 1.9.0, chúng tôi đã thêm một mô-đun mới media3-ui-compose-material3 với các nút và phần tử nội dung Material3 được tạo kiểu đầy đủ. Các thành phần này cho phép bạn tạo giao diện người dùng đa phương tiệ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 tạo kiểu giao diện người dùng riêng, bạn có thể dùng các khối dựng để xử lý mọi 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 cho các mô-đun giao diện người dùng Compose.

Chúng tôi cũng đang nỗ lực phát triển thêm nhiều thành phần Compose khác, chẳng hạn như thanh tua sẵn, một giải pháp thay thế hoàn chỉnh cho PlayerView ngay khi xuất xưởng, 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 phần tử có sẵn

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

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

Khi thiết lập MediaSession, bạn chỉ cần tạo một CastPlayer xung quanh ExoPlayer và thêm một 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 nhất quán định dạng AV1 bằng tiện ích đượ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 tiện ích AV1 được viết lại hoàn toàn dựa trên thư viện dav1d phổ biến. 

Tương tự như tất cả các mô-đun trình giải mã tiện ích, xin lưu ý rằng bạn cần tạo từ nguồn để kết hợp đúng mã gốc có liên quan. Việc kết hợp một 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ị. Tuy nhiên, vì bộ giải mã này chạy quá trình giải mã trong quy trình của bạn, nên bộ giải mã 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 lưu vào bộ nhớ đệm và quản lý bộ nhớ 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 rồi chuyển nội dung đó một cách liền mạch cho trình phát khi cần. Mặc dù có hiệu suất khá tốt, nhưng bạn vẫn phải cẩn thận để không vượt quá giới hạn bộ nhớ do 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 việc này trở nên dễ dàng và ổn định hơn nhiều:

  1. Hỗ trợ lưu vào 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 dải ô được 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 nhiều mục hơn để tải trước vì những 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 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. 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 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, đơ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 nhỏ cho ExoPlayer. Chỉ cần kể tên một vài ví dụ:

  • Tắt và bật tiếng – Chúng tôi đã có phương thức setVolume, nhưng hiện đã 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 người chơi bị kẹt – Trong một số trường hợp hiếm gặp, người chơi có thể bị kẹt ở trạng thái đệm hoặc phát mà không có tiến triển nào, chẳng hạn như do sự cố về bộ mã hoá và giải mã hoặc cấu hình sai. Người dùng của bạn sẽ cảm thấy khó chịu, nhưng bạn sẽ không bao giờ thấy những vấn đề này trong số liệu phân tích của mình! Để làm rõ hơn, trình phát hiện báo cáo StuckPlayerException khi phát hiện thấy trạng thái bị kẹt.
  • Theo mặc định, khoá chế độ thức – Trước đây, tính năng quản lý khoá chế độ thức yêu cầu chọn sử dụng, dẫn đến việc khó tìm thấy các trường hợp đặc biệt mà tiến trình phát có thể bị chậm trễ rất nhiều khi chạy ở chế độ nền. Hiện tại, tính năng này là chọn không tham gia, nên bạn không cần 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 theo cách thủ công trong quá trình phát.
  • Chế độ cài đặt đơn giản cho logic của nút phụ đề – Việc thay đổi TrackSelectionParameters thành "bật/tắt phụ đề" khó hơn dự kiến, vì vậy, chúng tôi đã thêm một lựa chọn boolean selectTextByDefault đơn giản cho trường hợp sử dụng này.

Đơn giản hoá các lựa chọn ưu tiên về nút đa phương tiện trong MediaSession

Cho đến nay, việc xác định lựa chọn ưu tiên về những nút sẽ xuất hiện trong ngăn thông báo về nội dung nghe nhìn trên Android Auto hoặc WearOS đòi hỏi bạn phải xác định các lệnh và nút 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 việc này trở nên đơn giản hơn nhiều – giờ đây, bạn có thể xác định các lựa chọn ưu tiên về nút đa phương tiệ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 về nút đa phương tiện có nút tua đi

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

Bản phát hành 1.9.0 giới thiệu CompositionPlayer trong chú thích @ExperimentalApi mới. Chú thích này cho biết rằng bạn có thể thử nghiệm chú thích đó, nhưng chú thích đó 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 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ọ đang diễn ra trước khi thực hiện quy trình xuất. Thao tác này sử dụng cùng một đối tượng Composition mà bạn sẽ truyề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 cho bản xem trước và xuất.

Bạn nên bắt đầu sử dụng CompositionPlayer và chia sẻ ý kiến phản hồi của bạn, đồng thời chú ý theo dõi các bài đăng và nội dung cập nhật sắp tới trong 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ộ trộn mặc định để ghi tệp vùng chứa nội dung nghe nhìn. Về nội bộ, InAppMp4Muxer phụ thuộc vào mô-đun Muxer của Media3, 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ù theo mặc định, Transformer không còn sử dụng MediaMuxer của nền tảng Android nữa, 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á các API điều chỉnh tốc độ để chỉnh sửa nội dung nghe nhìn. Chúng tôi đã ra mắt các phương thức mới ngay 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 pháp trước đây là sử dụng Effects#createExperimentalSpeedChangingEffects(). Chúng tôi đã ngừng sử dụng và sẽ xoá phương pháp này trong một bản phát hành sau này.

Giới thiệu các loại kênh 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 âm thanh đầu ra mong muốn trong quá trình tạo chuỗi. Thay đổi này đảm bảo việc xử lý các bản nhạc trở nên rõ ràng và mạnh mẽ hơn trên toàn bộ thành phần. 

Việc này được thực hiện thông qua một hàm khởi tạo EditedMediaItemSequence.Builder mới chấp nhận một nhóm 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 tĩnh tiện lợi 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 thuận tiện để có định nghĩa trình tự rõ ràng và đáng tin cậy hơn.

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

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

Vui lòng liên hệ qua Công cụ theo dõi vấn đề của Media3 nếu bạn gặp phải lỗi hoặc 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