下面列出了怎么用android.media.MediaDataSource的API类实例代码及写法,或者点击链接到github查看源代码。
private ThumbnailData generateVideoThumbnail(AttachmentId attachmentId, long timeUs) throws IOException {
if (Build.VERSION.SDK_INT < 23) {
Log.w(TAG, "Video thumbnails not supported...");
return null;
}
try (MediaDataSource dataSource = mediaDataSourceFor(attachmentId)) {
if (dataSource == null) return null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
MediaMetadataRetrieverUtil.setDataSource(retriever, dataSource);
Bitmap bitmap = retriever.getFrameAtTime(timeUs);
Log.i(TAG, "Generated video thumbnail...");
return bitmap != null ? new ThumbnailData(bitmap) : null;
}
}
private static @NonNull MediaInput createForAttachmentUri(@NonNull Context context, @NonNull Uri uri) {
AttachmentId partId = new PartUriParser(uri).getPartId();
if (!partId.isValid()) {
throw new AssertionError();
}
MediaDataSource mediaDataSource = DatabaseFactory.getAttachmentDatabase(context)
.mediaDataSourceFor(partId);
if (mediaDataSource == null) {
throw new AssertionError();
}
return new MediaInput.MediaDataSourceMediaInput(mediaDataSource);
}
@RequiresApi(23)
public synchronized @NonNull MediaDataSource getMediaDataSource(@NonNull Context context, @NonNull Uri uri) throws IOException {
return getBlobRepresentation(context,
uri,
ByteArrayMediaDataSource::new,
file -> EncryptedMediaDataSource.createForDiskBlob(getAttachmentSecret(context), file));
}
@RequiresApi(23)
public @Nullable MediaDataSource mediaDataSourceFor(@NonNull AttachmentId attachmentId) {
DataInfo dataInfo = getAttachmentDataFileInfo(attachmentId, DATA);
if (dataInfo == null) {
Log.w(TAG, "No data file found for video attachment...");
return null;
}
return EncryptedMediaDataSource.createFor(attachmentSecret, dataInfo.file, dataInfo.random, dataInfo.length);
}
/**
* {@link MediaMetadataRetriever#setDataSource(MediaDataSource)} tends to crash in native code on
* specific devices, so this just a wrapper to convert that into an {@link IOException}.
*/
@RequiresApi(23)
public static void setDataSource(@NonNull MediaMetadataRetriever retriever,
@NonNull MediaDataSource dataSource)
throws IOException
{
try {
retriever.setDataSource(dataSource);
} catch (Exception e) {
throw new IOException(e);
}
}
private @Nullable String getVideoBlurHash(@NonNull Attachment attachment) throws IOException {
if (attachment.getThumbnailUri() != null) {
return BlurHashEncoder.encode(PartAuthority.getAttachmentStream(context, attachment.getThumbnailUri()));
}
if (attachment.getBlurHash() != null) return attachment.getBlurHash().getHash();
if (Build.VERSION.SDK_INT < 23) {
Log.w(TAG, "Video thumbnails not supported...");
return null;
}
try (MediaDataSource dataSource = DatabaseFactory.getAttachmentDatabase(context).mediaDataSourceFor(attachmentId)) {
if (dataSource == null) return null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
MediaMetadataRetrieverUtil.setDataSource(retriever, dataSource);
Bitmap bitmap = retriever.getFrameAtTime(1000);
if (bitmap != null) {
Bitmap thumb = Bitmap.createScaledBitmap(bitmap, 100, 100, false);
bitmap.recycle();
Log.i(TAG, "Generated video thumbnail...");
String hash = BlurHashEncoder.encode(thumb);
thumb.recycle();
return hash;
} else {
return null;
}
}
}
/**
* @param upperSizeLimit A upper size to transcode to. The actual output size can be up to 10% smaller.
*/
public InMemoryTranscoder(@NonNull Context context, @NonNull MediaDataSource dataSource, @Nullable Options options, long upperSizeLimit) throws IOException, VideoSourceException {
this.context = context;
this.dataSource = dataSource;
this.options = options;
final MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
try {
mediaMetadataRetriever.setDataSource(dataSource);
} catch (RuntimeException e) {
Log.w(TAG, "Unable to read datasource", e);
throw new VideoSourceException("Unable to read datasource", e);
}
long upperSizeLimitWithMargin = (long) (upperSizeLimit / 1.1);
this.inSize = dataSource.getSize();
this.duration = getDuration(mediaMetadataRetriever);
this.inputBitRate = bitRate(inSize, duration);
this.targetVideoBitRate = getTargetVideoBitRate(upperSizeLimitWithMargin, duration);
this.upperSizeLimit = upperSizeLimit;
this.transcodeRequired = inputBitRate >= targetVideoBitRate * 1.2 || inSize > upperSizeLimit || containsLocation(mediaMetadataRetriever) || options != null;
if (!transcodeRequired) {
Log.i(TAG, "Video is within 20% of target bitrate, below the size limit, contained no location metadata or custom options.");
}
this.fileSizeEstimate = (targetVideoBitRate + AUDIO_BITRATE) * duration / 8000;
this.memoryFileEstimate = (long) (fileSizeEstimate * 1.1);
this.outputFormat = targetVideoBitRate < LOW_RES_TARGET_VIDEO_BITRATE
? LOW_RES_OUTPUT_FORMAT
: OUTPUT_FORMAT;
}
@TargetApi(23)
public void setVideoFromMediaDataSource(MediaDataSource mediaDataSource) {
reset();
mediaPlayer.setDataSource(mediaDataSource);
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(mediaDataSource);
onDataSourceSet(retriever);
}
public MediaDataSourceMediaInput(@NonNull MediaDataSource mediaDataSource) {
this.mediaDataSource = mediaDataSource;
}
public static MediaDataSource createFor(@NonNull AttachmentSecret attachmentSecret, @NonNull File mediaFile, @Nullable byte[] random, long length) {
return new ModernEncryptedMediaDataSource(attachmentSecret, mediaFile, random, length);
}
public static MediaDataSource createForDiskBlob(@NonNull AttachmentSecret attachmentSecret, @NonNull File mediaFile) {
return new ModernEncryptedMediaDataSource(attachmentSecret, mediaFile, null, mediaFile.length() - 32);
}