Media enhancements
VolumeShaper
There is a new
VolumeShaper
class. Use it to perform short automated volume transitions like fade-ins, fade-outs, and cross fades. See Controlling Amplitude with VolumeShaper to learn more.Audio focus enhancements
Audio apps share the audio output on a device by requesting and abandoning audio focus. An app handles changes in focus by starting or stopping playback, or ducking its volume. There is a new
AudioFocusRequest
class. Using this class as the parameter ofrequestAudioFocus()
, apps have new capabilites when handling changes in audio focus:automatic ducking and delayed focus gain.Media metrics
A new
getMetrics()
method returns a PersistableBundle
object containing configuration and performance information, expressed as a map of attributes and values. The getMetrics()
method is defined for these media classes:MediaPlayer.getMetrics()
MediaRecorder.getMetrics()
MediaCodec.getMetrics()
MediaExtractor.getMetrics()
Metrics are collected separately for each instance and persist for the lifetime of the instance. If no metrics are available the method returns null. The actual metrics returned depend on the class.
MediaPlayer
Starting in Android 8.0 (API level 26) MediaPlayer can playback DRM-protected material and HLS sample-level encrypted media.
Android 8.0 introduces a new overloaded
seekTo()
command that provides fine-grained control when seeking to a frame. It includes a second parameter that specifies a seek mode:SEEK_PREVIOUS_SYNC
moves the media position to a sync (or key) frame associated with a data source that is located right before or at the given time.SEEK_NEXT_SYNC
moves the media position to a sync (or key) frame associated with a data source that is located right after or at the given time.SEEK_CLOSEST_SYNC
moves the media position to a sync (or key) frame associated with a data source that is located closest to or at the given time.SEEK_CLOSEST
moves the media position to a frame (not necessarily a sync or key frame) associated with a data source that is located closest to or at the given time.
When seeking continuously, apps should use any of the
SEEK_
modes rather than SEEK_CLOSEST
, which runs relatively slower but can be more precise.MediaRecorder
- MediaRecorder now supports the MPEG2_TS format which is useful for streaming:
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);
- The
MediaMuxer
can now handle any number of audio and video streams. You are no longer limited to one audio track and/or one video track. UseaddTrack()
to mix as many tracks as you like. - The
MediaMuxer
can also add one or more metadata tracks containing user-defined per-frame information. The format of the metadata is defined by your application. The metadata track is only supported for MP4 containers.
Metadata can be useful for offline processing. For example, gyro signals from the sensor could be used to perform video stabilization.
When adding a metadata track, the track's mime format must start with the prefix "application/". Writing metadata is the same as writing video/audio data except that the data does not come from a
MediaCodec
. Instead, the app passes a ByteBuffer
with an associated timestamp to the writeSampleData()
method. The timestamp must be in the same time base as the video and audio tracks.
The generated MP4 file uses the
TextMetaDataSampleEntry
defined in section 12.3.3.2 of the ISOBMFF to signal the metadata's mime format. When using MediaExtractor
to extract the file with metadata track, the mime format of the metadata will be extracted into MediaFormat
.Improved media file access
The Storage Access Framework (SAF) allows apps to expose a custom
DocumentsProvider
, which can provide access to files in a data source to other apps. In fact, a documents provider can even provide access to files that reside on network storage or that use a protocol like Media Transfer Protocol (MTP).
However, accessing large media files from a remote data source introduces some challenges:
- Media players require seekable access to a file from a documents provider. In cases where a large media file resides on a remote data source, the documents provider must fetch all of the data in advance and create a snapshot file descriptor. The media player cannot play the file without the file descriptor, thus playback cannot begin until the documents provider finishes downloading the file.
- Media collection managers, such as photo apps, must traverse a series of access URIs to reach media that's stored on an external SD card via scoped folders. This access pattern makes mass operations on media—such as moving, copying, and deleting—quite slow.
- Media collection managers cannot determine a document's location given its URI. This makes it difficult for these types of apps to allow users to choose where to save a media file.
Android 8.0 addresses each of these challenges by improving the Storage Access Framework.
Custom document providers
Starting in Android 8.0, the Storage Access Framework allows custom documents providersto create seekable file descriptors for files residing in a remote data source. The SAF can open a file to get a native seekable file descriptor. The SAF then delivers discrete bytes requests to the documents provider. This feature allows a documents provider to return the exact range of bytes that a media player app has requested instead of caching the entire file in advance.
To use this feature, you need to call the new
StorageManager.openProxyFileDescriptor()
method. TheopenProxyFileDescriptor()
method accepts a ProxyFileDescriptorCallback
object as a callback. The SAF invokes the callback any time a client application performs file operations on the file descriptor returned from the documents provider.Direct document access
As of Android 8.0 (API level 26), you can use the
getDocumentUri()
method to get a URI that references the same document as the given mediaUri
. However, because the returned URI is backed by a DocumentsProvider
, media collection managers can access the document directly, without having to traverse trees of scoped directories. As a result, the media managers can perform file operations on the document significantly more quickly.
Caution: The
getDocumentUri()
method only locates media files; it doesn't grant apps permission to access those files. To learn more about how to obtain access permission to media files, see the reference documentation.Paths to documents
When using the Storage Access Framework in Android 8.0 (API level 26), you can use the
findDocumentPath()
method, available in both the DocumentsContract
andDocumentsProvider
classes, to determine the path from the root of a file system given a document's ID. The method returns this path in a DocumentsContract.Path
object. In cases where a file system has multiple defined paths to the same document, the method returns the path that is used most often to reach the document with the given ID.
This functionality is particularly useful in the following scenarios:
- Your app uses a "save as" dialog that displays the location of a particular document.
- Your app shows folders in a search results view and must load the child documents that are within a particular folder if the user selects that folder.
Note: If your app has permission to access only some of the documents in the path, the return value of
findDocumentPath()
includes only the folders and documents that your app can access.Monitoring audio playback
The
AudioManager
system service maintains a list of active AudioPlaybackConfiguration
objects, each of which contains information about a particular audio playback session. Your app can retrieve the set of currently-active configurations by calling getActivePlaybackConfigurations()
.
As of Android 8.0 (API level 26), you can register a callback that notifies your app when one or more
AudioPlaybackConfiguration
objects has changed. To do so, call registerAudioPlaybackCallback()
, passing in an instance ofAudioManager.AudioPlaybackCallback
. The AudioManager.AudioPlaybackCallback
class contains the onPlaybackConfigChanged()
method, which the system calls when the audio playback configuration changes.
No comments:
Post a Comment