#exoplayer https://theinshotproapk.com/category/app/exoplayer/ Download InShot Pro APK for Android, iOS, and PC Fri, 19 Dec 2025 22:00:00 +0000 en-US hourly 1 https://theinshotproapk.com/wp-content/uploads/2021/07/cropped-Inshot-Pro-APK-Logo-1-32x32.png #exoplayer https://theinshotproapk.com/category/app/exoplayer/ 32 32 Media3 1.9.0 – What’s new https://theinshotproapk.com/media3-1-9-0-whats-new/ Fri, 19 Dec 2025 22:00:00 +0000 https://theinshotproapk.com/media3-1-9-0-whats-new/ Posted by Kristina Simakova, Engineering Manager Media3 1.9.0 – What’s new? Media3 1.9.0 is out! Besides the usual bug fixes ...

Read more

The post Media3 1.9.0 – What’s new appeared first on InShot Pro.

]]>

Posted by Kristina Simakova, Engineering Manager



Media3 1.9.0 – What’s new?

Media3 1.9.0 is out! Besides the usual bug fixes and performance improvements, the latest release also contains four new or largely rewritten modules:

  • media3-inspector – Extract metadata and frames outside of playback

  • media3-ui-compose-material3 – Build a basic Material3 Compose Media UI in just a few steps

  • media3-cast – Automatically handle transitions between Cast and local playbacks

  • media3-decoder-av1 – Consistent AV1 playback with the rewritten extension decoder based on the dav1d library

We also added caching and memory management improvements to PreloadManager, and provided several new ExoPlayer, Transformer and MediaSession simplifications. 

This release also gives you the first experimental access to CompositionPlayer to preview media edits.  


Read on to find out more, and as always please check out the full release notes for a comprehensive overview of changes in this release.

Extract metadata and frames outside of playback

There are many cases where you want to inspect media without starting a playback. For example, you might want to detect which formats it contains or what its duration is, or to retrieve thumbnails.

The new media3-inspector module combines all utilities to inspect media without playback in one place:

  • MetadataRetriever to read duration, format and static metadata from a MediaItem.

  • FrameExtractor to get frames or thumbnails from an item. 

  • MediaExtractorCompat as a direct replacement for the Android platform MediaExtractor class, to get detailed information about samples in the file.

MetadataRetriever and FrameExtractor follow a simple AutoCloseable pattern. Have a look at our new guide pages for more details.

suspend fun extractThumbnail(mediaItem: MediaItem) {
  FrameExtractor.Builder(context, mediaItem).build().use {
    val thumbnail = frameExtractor.getThumbnail().await()
  } 
}

Build a basic Material3 Compose Media UI in just a few steps

In previous releases we started providing connector code between Compose UI elements and your Player instance. With Media3 1.9.0, we added a new module media3-ui-compose-material3 with fully-styled Material3 buttons and content elements. They allow you to build a media UI in just a few steps, while providing all the flexibility to customize style. If you prefer to build your own UI style, you can use the building blocks that take care of all the update and connection logic, so you only need to concentrate on designing the UI element. Please check out our extended guide pages for the Compose UI modules.


We are also still working on even more Compose components, like a prebuilt seek bar, a complete out-of-the-box replacement for PlayerView, as well as subtitle and ad integration.

@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)
    }
  }
}

Simple Compose player UI with out-of-the-box elements

Automatically handle transitions between Cast and local playbacks

The CastPlayer in the media3-cast module has been rewritten to automatically handle transitions between local playback (for example with ExoPlayer) and remote Cast playback.

When you set up your MediaSession, simply build a CastPlayer around your ExoPlayer and add a MediaRouteButton to your UI and you’re done!

// MediaSession setup with CastPlayer 
val exoPlayer = ExoPlayer.Builder(context).build()
val castPlayer = CastPlayer.Builder(context).setLocalPlayer(exoPlayer).build()
val session = MediaSession.Builder(context, player)
// MediaRouteButton in UI 
@Composable fun UIWithMediaRouteButton() {
  MediaRouteButton()
}

New CastPlayer integration in Media3 session demo app

Consistent AV1 playback with the rewritten extension based on dav1d

The 1.9.0 release contains a completely rewritten AV1 extension module based on the popular dav1d library.

As with all extension decoder modules, please note that it requires building from source to bundle the relevant native code correctly. Bundling a decoder provides consistency and format support across all devices, but because it runs the decoding in your process, it’s best suited for content you can trust. 

Integrate caching and memory management into PreloadManager

We made our PreloadManager even better as well. It already enabled you to preload media into memory outside of playback and then seamlessly hand it over to a player when needed. Although pretty performant, you still had to be careful to not exceed memory limits by accidentally preloading too much. So with Media3 1.9.0, we added two features that makes this a lot easier and more stable:


  1. Caching support – When defining how far to preload, you can now choose PreloadStatus.specifiedRangeCached(0, 5000) as a target state for preloaded items. This will add the specified range to your cache on disk instead of loading the data to memory. With this, you can provide a much larger range of items for preloading as the ones further away from the current item no longer need to occupy memory. Note that this requires setting a Cache in DefaultPreloadManager.Builder.

  2. Automatic memory management – We also updated our LoadControl interface to better handle the preload case so you are now able to set an explicit upper memory limit for all preloaded items in memory. It’s 144 MB by default, and you can configure the limit in DefaultLoadControl.Builder. The DefaultPreloadManager will automatically stop preloading once the limit is reached, and automatically releases memory of lower priority items if required.

Rely on new simplified default behaviors in ExoPlayer

As always, we added lots of incremental improvements to ExoPlayer as well. To name just a few:

  • Mute and unmute – We already had a setVolume method, but have now added the convenience mute and unmute methods to easily restore the previous volume without keeping track of it yourself.

  • Stuck player detection – In some rare cases the player can get stuck in a buffering or playing state without making any progress, for example, due to codec issues or misconfigurations. Your users will be annoyed, but you never see these issues in your analytics! To make this more obvious, the player now reports a StuckPlayerException when it detects a stuck state.

  • Wakelock by default – The wake lock management was previously opt-in, resulting in hard to find edge cases where playback progress can be delayed a lot when running in the background. Now this feature is opt-out, so you don’t have to worry about it and can also remove all manual wake lock handling around playback.

  • Simplified setting for CC button logic Changing TrackSelectionParameters to say “turn subtitles on/off” was surprisingly hard to get right, so we added a simple boolean selectTextByDefault option for this use case.

Simplify your media button preferences in MediaSession

Until now, defining your preferences for which buttons should show up in the media notification drawer on Android Auto or WearOS required defining custom commands and buttons, even if you simply wanted to trigger a standard player method.

Media3 1.9.0 has new functionality to make this a lot simpler – you can now define your media button preferences with a standard player command, requiring no custom command handling at all.

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()
))

Media button preferences with fast forward button

CompositionPlayer for real-time preview

The 1.9.0 release introduces CompositionPlayer under a new @ExperimentalApi annotation. The annotation indicates that it is available for experimentation, but is still under development. 

CompositionPlayer is a new component in the Media3 editing APIs designed for real-time preview of media edits. Built upon the familiar Media3 Player interface, CompositionPlayer allows users to see their changes in action before committing to the export process. It uses the same Composition object that you would pass to Transformer for exporting, streamlining the editing workflow by unifying the data model for preview and export.

We encourage you to start using CompositionPlayer and share your feedback, and keep an eye out for forthcoming posts and updates to the documentation for more details.

InAppMuxer as a default muxer in Transformer

Transformer now uses InAppMp4Muxer as the default muxer for writing media container files. Internally, InAppMp4Muxer depends on the Media3 Muxer module, providing consistent behaviour across all API versions. 

Note that while Transformer no longer uses the Android platform’s MediaMuxer by default, you can still provide FrameworkMuxer.Factory via setMuxerFactory if your use case requires it.

New speed adjustment APIs

The 1.9.0 release simplifies speed adjustments APIs for media editing. We’ve introduced new methods directly on EditedMediaItem.Builder to control speed, making the API more intuitive. You can now change the speed of a clip by calling setSpeed(SpeedProvider provider) on the 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()


This new approach replaces the previous method of using Effects#createExperimentalSpeedChangingEffects(), which we’ve deprecated and will remove in a future release.

Introducing track types for EditedMediaItemSequence

In the 1.9.0 release, EditedMediaItemSequence requires specifying desired output track types during sequence creation. This change ensures track handling is more explicit and robust across the entire Composition.

This is done via a new EditedMediaItemSequence.Builder constructor that accepts a set of track types (e.g., C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO). 

To simplify creation, we’ve added new static convenience methods:

  • EditedMediaItemSequence.withAudioFrom(List<EditedMediaItem>)

  • EditedMediaItemSequence.withVideoFrom(List<EditedMediaItem>)

  • EditedMediaItemSequence.withAudioAndVideoFrom(List<EditedMediaItem>)

We encourage you to migrate to the new constructor or the convenience methods for clearer and more reliable sequence definitions.

Example of creating a video-only sequence:

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


Please get in touch via the Media3 issue Tracker if you run into any bugs, or if you have questions or feature requests. We look forward to hearing from you!

The post Media3 1.9.0 – What’s new appeared first on InShot Pro.

]]>
Elevating media playback: Introducing preloading with Media3 – Part 1 https://theinshotproapk.com/elevating-media-playback-introducing-preloading-with-media3-part-1/ Fri, 05 Sep 2025 17:00:00 +0000 https://theinshotproapk.com/elevating-media-playback-introducing-preloading-with-media3-part-1/ Posted by Mayuri Khinvasara Khabya – Developer Relations Engineer (LinkedIn and X) In today’s media-centric apps, delivering a smooth, uninterrupted ...

Read more

The post Elevating media playback: Introducing preloading with Media3 – Part 1 appeared first on InShot Pro.

]]>

Posted by Mayuri Khinvasara Khabya – Developer Relations Engineer (LinkedIn and X)

In today’s media-centric apps, delivering a smooth, uninterrupted playback experience is key to a delightful user experience. Users expect their videos to start instantly and play seamlessly without pauses.

The core challenge is latency. Traditionally, a video player only starts its work—connecting, downloading, parsing, buffering—after the user has chosen an item for playback. This reactive approach is slow for today’s short form video context. The solution is to be proactive. We need to anticipate what the user will watch next and get the content ready ahead of time. This is the essence of preloading.

The key benefits of preloading include:

    • 🚀 Faster Playback Start: Videos are already ready to go, leading to quicker transitions between items and a more immediate start.
    • 📉 Reduced Buffering: By proactively loading data, playback is far less likely to stall, for example due to network hiccups.
    • ✨ Resulting smoother User Experience: The combination of faster starts and less buffering creates a more fluid, seamless interaction for users to enjoy.

In this three-part series, we’ll introduce and deep dive into Media3’s powerful utilities for (pre)loading components.

    • In Part 1, we’ll cover the foundations: understanding the different preloading strategies available in Media3, enabling PreloadConfiguration and setting up the DefaultPreloadManager, enabling your app to preload items. By the end of this blog, you should be able to preload and play media items with your configured ranking and duration.
    • In Part 2, we’ll get into more advanced topics of DefaultPreloadManager: using listeners for analytics, exploring production-ready best practices like the sliding window pattern and custom shared components of DefaultPreloadManager and ExoPlayer.
    • In Part 3, we’ll dive deep into disk caching with DefaultPreloadManager.

Preloading to the rescue! 🦸‍♀️

The core idea behind preloading is simple: load media content before you need it. By the time a user swipes to the next video, the first segments of the video are already downloaded and available, ready for immediate playback.

Think of it like a restaurant. A busy kitchen doesn’t wait for an order to start chopping onions. 🧅 They do their prep work in advance. Preloading is the prep work for your video player.

When enabled, preloading can help minimize join latency when a user skips to the next item before the playback buffer reaches the next item. The first period of the next window is prepared and video, audio and text samples are buffered. The preloaded period is later queued into the player with buffered samples immediately available and ready to be fed to the codec for rendering.

In Media3 there are two primary APIs for preloading, each suited for different use cases. Choosing the right API is the first step.

1. Preloading playlist items with PreloadConfiguration

This is the simple approach, useful for linear, sequential media like playlists where the playback order is predictable (like a series of episodes). You give the player the full list of media items using ExoPlayer’s playlist APIs and set the PreloadConfiguration for the player, then it automatically preloads the next items in the sequence as configured. This API attempts to optimize the join latency when a user skips to the next item before the playback buffer already overlaps into the next item.

Preloading is only started when no media is being loaded for the ongoing playback, which prevents it from competing for bandwidth with the primary playback.

If you’re still not sure whether you need preloading, this API is a great low-lift option to try it out!

player.preloadConfiguration =
    PreloadConfiguration(/* targetPreloadDurationUs= */ 5_000_000L)

With the PreloadConfiguration above, the player tries to preload five seconds of media for the next item in the playlist.

Once opted-in, playlist preloading can be turned off again by using PreloadConfiguration.DEFAULT to disable playlist preloading:

player.preloadConfiguration = PreloadConfiguration.DEFAULT

2. Preloading dynamic lists with PreloadManager

For dynamic UIs like vertical feeds or carousels, where the “next” item is determined by user interaction, the PreloadManager API is appropriate. This is a new powerful, standalone component within the Media3 ExoPlayer library specifically designed to proactively preload. It manages a collection of potential MediaSources, prioritizing them based on proximity to the user’s current position and offers granular control over what to preload, suitable for complex scenarios like dynamic feeds of short form videos.

Setting Up Your PreloadManager

The DefaultPreloadManager is the canonical implementation for PreloadManager.

The builder of DefaultPreloadManager can build both the DefaultPreloadManager and any ExoPlayer instances that will play its preloaded content. To create a DefaultPreloadManager, you will need to pass a TargetPreloadStatusControl, which the preload manager can query to find out how much to load for an item. We will explain and define an example of TargetPreloadStatusControl in the section below.

val preloadManagerBuilder =
DefaultPreloadManager.Builder(context, targetPreloadStatusControl)
val preloadManager = val preloadManagerBuilder.build()

// Build ExoPlayer with DefaultPreloadManager.Builder
val player = preloadManagerBuilder.buildExoPlayer()

Using the same builder for both the ExoPlayer and DefaultPreloadManager is necessary, which ensures that the components under the hood of them are correctly shared.

And that’s it! You now have a manager ready to receive instructions.

Configuring Duration and Ranking with TargetPreloadStatusControl

What if you want to preload, say, 10 seconds of video ? You can provide the position of your media items in the carousel, and the DefaultPreloadManager prioritizes loading the items based on how close it is to the item the user is currently playing.

If you want to control how much duration of the item to preload, you can tell that with DefaultPreloadManager.PreloadStatus you return.

For example,

    • Item ‘A’ is the highest priority, load 5 seconds of video.
    • Item ‘B’ is medium priority but when you get to it, load 3 seconds of video.
    • Item ‘C’ is less priority, load only tracks.
    • Item ‘D’ is even less of a priority, just prepare.
    • Any other items are far away, Don’t preload anything.

This granular control can help you optimize your resource utilization which is recommended for a seamless playback.

import androidx.media3.exoplayer.DefaultPreloadManager.PreloadStatus


class MyTargetPreloadStatusControl(
    currentPlayingIndex: Int = C.INDEX_UNSET
) : TargetPreloadStatusControl<Int,PreloadStatus> {


    // The app is responsible for updating this based on UI state
    override fun getTargetPreloadStatus(index: Int): PreloadStatus? {

        val distance = index - currentPlayingIndex

        // Adjacent items (Next): preload 5 seconds
        if (distance == 1) { 
        // Return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED and suggest loading // 5000ms from the default start position
                    return PreloadStatus.specifiedRangeLoaded(5000L)
                } 

        // Adjacent items (Previous): preload 3 seconds
        else if (distance == -1) { 
        // Return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED //and suggest loading 3000ms from the default start position
                    return PreloadStatus.specifiedRangeLoaded(3000L)
                } 

        // Items two positions away: just select tracks
        else if (distance) == 2) {
        // Return a PreloadStatus that is labelled by STAGE_TRACKS_SELECTED
                    return PreloadStatus.TRACKS_SELECTED
                } 

        // Items four positions away: just select prepare
        else if (abs(distance) <= 4) {
        // Return a PreloadStatus that is labelled by STAGE_SOURCE_PREPARED
                    return PreloadStatus.SOURCE_PREPARED
                }

             // All other items are too far away
             return null
            }
}

Tip: PreloadManager can keep both the previous and next items preloaded, whereas the PreloadConfiguration will only look ahead to the next items.

Managing Preloading Items

With your manager created, you can start telling it what to work on. As your user scrolls through a feed, you’ll identify the upcoming videos and add them to the manager. The interaction with the PreloadManager is a state-driven conversation between your UI and the preloading engine.

1. Add Media Items

As you populate your feed, you must inform the manager of the media it needs to track. If you are starting, you could add the entire list you want to preload. Subsequently you can keep adding a single item to the list as and when required. You have full control over what items are in the preloading list which means you also have to manage what is added and removed from the manager.

val initialMediaItems = pullMediaItemsFromService(/* count= */ 20)
for (index in 0 until initialMediaItems.size) {
    preloadManager.add(
        initialMediaItems.get(index),index)
    )
}

The manager will now start fetching data for this MediaItem in the background.

After adding, tell the manager to re-evaluate its new list (hinting that something has changed like adding/ removing an item, or the user switches to play a new item.)

preloadManager.invalidate()

2. Retrieve and Play an Item

Here comes the main playback logic. When the user decides to play that video, you don’t need to create a new MediaSource. Instead, you ask the PreloadManager for the one it has already prepared. You can retrieve the MediaSource from the Preload Manager using the MediaItem.

If the retrieved item from the PreloadManager is null, that means the mediaItem is not preloaded yet or added to the PreloadMamager, so you choose to set the mediaItem directly.

// When a media item is about to displ​​ay on the screen
val mediaSource = preloadManager.getMediaSource(mediaItem)
if (mediaSource!= null) {
  player.setMediaSource(mediaSource)
} else {
  // If mediaSource is null, that mediaItem hasn't been added yet.
  // So, send it directly to the player.
  player.setMediaItem(mediaItem)
}
player.prepare()
// When the media item is displaying at the center of the screen
player.play()

By preparing the MediaSource retrieved from the PreloadManager, you seamlessly transition from preloading to playback, using the data that’s already in memory. This is what makes the start time faster.

3. Keep the current index in sync with the UI

Since our feed / list could be dynamic, it’s important to notify the PreloadManager of your current playing index so that it can always prioritize items nearest to your current index for preloading.

preloadManager.setCurrentPlayingIndex(currentIndex)
// Need to call invalidate() to update the priorities
preloadManager.invalidate()

4. Remove an Item

To keep the manager efficient, you should remove items it no longer needs to track, such as items that are far away from the user’s current position.

// When an item is too far from the current playing index
preloadManager.remove(mediaItem)

If you need to clear all items at once, you can call preloadManager.reset().

5. Release the Manager

When you no longer need the PreloadManager (e.g., when your UI is destroyed), you must release it to free up its resources. A good place to do this is where you’re already releasing your Player’s resources. It’s recommended to release the manager before the player as the player can continue to play if you don’t need any more preloading.

// In your Activity's onDestroy() or Composable's onDispose
preloadManager.release()

Demo time

Check it live in action 👍

In the demo below , we see the impact of PreloadManager on the right side which has faster load times, whereas the left side shows the existing experience. You can also view the code sample for the demo. (Bonus: It also displays startup latency for every video)

Jetpack Media3 API for fast loading of short videos [PreloadManager]

What’s Next?

And that’s a wrap for Part 1! You now have the tools to build a dynamic preloading system. You can either use PreloadConfiguration to preload the next item of a playlist in ExoPlayer or set up a DefaultPreloadManager, add and remove items on the fly, configure the target preload status, and correctly retrieve the preloaded content for playback.

In Part 2, we’ll go deeper on the DefaultPreloadManager. We’ll explore how to listen for preloading events, discuss best practices like using a sliding window to avoid memory issues, and peek under the hood at custom shared components of ExoPlayer and DefaultPreloadManager.

Do you have any feedback to share? We are eager to hear from you.

Stay tuned, and go make your app faster! 🚀

The post Elevating media playback: Introducing preloading with Media3 – Part 1 appeared first on InShot Pro.

]]>
Media3 1.8.0 – What’s new? https://theinshotproapk.com/media3-1-8-0-whats-new/ Mon, 11 Aug 2025 19:00:00 +0000 https://theinshotproapk.com/media3-1-8-0-whats-new/ Posted by Toni Heidenreich – Engineering Manager This release includes several bug fixes, performance improvements, and new features. Read on ...

Read more

The post Media3 1.8.0 – What’s new? appeared first on InShot Pro.

]]>

Posted by Toni Heidenreich – Engineering Manager

This release includes several bug fixes, performance improvements, and new features. Read on to find out more, and as always please check out the full release notes for a comprehensive overview of changes in this release.

Scrubbing in ExoPlayer

This release introduces a scrubbing mode in ExoPlayer, designed to optimize performance for frequent, user-driven seeks, like dragging a seek bar handle. You can enable it with ExoPlayer.setScrubbingModeEnabled(true). We’ve also integrated this into PlayerControlView in the UI module where it can be enabled with either time_bar_scrubbing_enabled=”true” in XML or the setTimeBarScrubbingEnabled(boolean) method. Media3 1.8.0 contains the first batch of scrubbing improvements, with more to come in 1.9.0!

moving image showing repeated seeking while scrubbing with scrubbing mode off in ExoPlayer

Repeated seeking while scrubbing with scrubbing mode OFF

moving image showing repeated seeking while scrubbing with scrubbing mode on in ExoPlayer

Repeated seeking while scrubbing with scrubbing mode ON

Live streaming ads with HLS interstitials

Extending the initial support for VOD in Media3 1.6.0, HlsInterstitialsAdsLoader now supports live streams and asset lists for all your server-guided ad insertion (SGAI) needs. The Google Ads Manager team explains how SGAI works. Follow our documentation for how to integrate HLS interstitals into your app.

chart of HLS intertitials processing flow from content server to ads server to Exoplayer

HLS interstitials processing flow

Duration retrieval without playback

MetadataRetriever has been significantly updated – it’s now using an AutoCloseable pattern and lets you retrieve the duration of media items without playback. This means Media3 now offers the full functionality of the Android platform MediaMetadataRetriever but without having to worry about device specific quirks and cross-process communication (some parts like frame extraction are still experimental, but we’ll integrate them properly in the future).

try {
  MetadataRetriever.Builder(context, mediaItem).build().use {
     val trackInfo = it.retrieveTrackGroups().await()
     val duration = it.retrieveDurationUs().await()
  }
} catch (e: IOException) {
  handleFailure(e)
}

Partial downloads, XR audio routing and more efficient playback

There were several other improvements and bug fixes across ExoPlayer and playback related components. To name just a few:

    • Downloader implementations now support partial downloads, with a new PreCacheHelper to organize manual caching of single items. This will be integrated into ExoPlayer’s DefaultPreloadManager in Media3 1.9.0 for an even more seamless caching and preloading experience.
    • When created with a Context with a virtual device ID, ExoPlayer now automatically routes the audio to the virtual XR device for that ID.
    • We enabled more efficient interactions with Android’s MediaCodec, for example skipping buffers that are not needed earlier in the pipeline.

Playback resumption in demo app and better notification defaults

The MediaSession module has a few changes and improvements for notification handling. It’s now keeping notifications for longer by default, for example when playback is paused, stopped or failed, so that a user has more time to resume playback in your app. Notifications for live streams (in particular with DVR windows) also became more useful by removing the confusing DVR window duration and progress from the notification.

The media session demo app now also supports playback resumption to showcase how the feature can be integrated into your app! It allows the user to resume playback long after your app has been terminated and even after reboot.

Media resumption notification after device reboot

Media resumption notification after device reboot

Faster trim operations with edit list support

We are continuing to add optimizations for faster trim operations to Transformer APIs. In the new 1.8.0 release, we introduced support for trimming using MP4 edit lists. Call experimentalSetMp4EditListTrimEnabled(true) to make trim-only edits significantly faster.

val transformer = Transformer.Builder(requireContext())
        .addListener(transformerListener)
        .experimentalSetMp4EditListTrimEnabled(true)
        .build()

A standard trimming operation often requires a full re-transcoding of the video, even for a simple trim. This meant decoding, re-encoding the entire file, which is a time-consuming and resource-intensive process. With MP4 edit list support, Transformer can now perform “trim-only” edits much more efficiently. Instead of re-encoding, it leverages the existing encoded samples and defines a “pre-roll” within the edit list. This pre-roll essentially tells the player where to start playback within an existing encoded sample, effectively skipping the unwanted beginning portion.

The following diagram illustrates how this works:

processing overview for faster trim optimizations

Processing overview for faster trim optimizations

As illustrated above, each file contains encoded samples and each sample begins with a keyframe. The red line indicates the intended clip point in the original file, allowing us to safely discard two first samples. The major difference in this approach lies in how we handle the third encoded sample. Instead of running a transcoding operation, we transmux this sample and define a pre-roll for a video start position. This significantly accelerates the export operation; however this optimization is only applicable if no other effects are applied. Player implementations may also ignore the pre-roll component of the final video and play from the start of the encoded sample.

Chipset specific optimizations with CodecDbLite

CodecDBLite optimizes two elements of encoder configuration on a chipset-by-chipset basis: codec selection and B-frames. Depending on the chipset, these parameters can have either a positive or adverse impact on video quality. CodecDB Lite leverages benchmark data collected on production devices to recommend a configuration that achieves the maximum user-perceived quality for the developer’s target bitrate. By enabling CodecDB Lite, developers can leverage advanced video codecs and features without worrying about whether or not they work on a given device.

To use CodecDbLite, simply call setEnableCodecDbLite(true) when building the encoder factory:

val transformer =
    Transformer.Builder()
        .setEncoderFactory(
            DefaultEncoderFactory.Builder()
                .setEnableCodecDbLite(true)
                .build()
        )
        .build()

New Composition demo

The Composition Demo app has been refreshed, and is now built entirely with Kotlin and Compose to showcase advanced multi-asset editing capabilities in Media3. Our team is actively extending the APIs, and future releases will introduce more advanced editing features, such as transitions between media items and other more advanced video compositing settings.

Adaptive-first: Editing flows can get complicated, so it helps to take advantage of as much screen real estate as possible. With the adaptive layouts provided by Jetpack Compose, such as the supporting pane layout, we can dynamically adapt the UI based on the device’s screen size.

new Composition demo app

Processing overview for faster trim optimizations

Multi-asset video compositor: We’ve added a custom video compositor that demonstrates how to arrange input media items into different layouts, such as a 2×2 grid or a picture-in-picture overlay. These compositor settings are applied to the Composition, and can be used both with CompositionPlayer for preview and Transformer for export.

picture-in-picture video overlay in the Composition demo app

Picture-in-picture video overlay in the Composition demo app

Get started with Media3 1.8.0

Please get in touch via the Media3 issue Tracker if you run into any bugs, or if you have questions or feature requests. We look forward to hearing from you!

The post Media3 1.8.0 – What’s new? appeared first on InShot Pro.

]]>