【发布时间】:2020-04-12 18:37:34
【问题描述】:
我正在研究 Android 在应用程序中显示 H264 视频的可能性。
视频流位于 mp4 容器内,可作为字节数组以逐块方式使用。
(我也可以使用MediaCodec,但我不想搞乱时间。)
我现在正在研究 ExoPlayer,但我对如何将 mp4 片段输入其中有点困惑:
- DASH 的 DashMediaSource。
- 用于 SmoothStreaming 的 SsMediaSource。
- 用于 HLS 的 HlsMediaSource。
- ProgressiveMediaSource 用于常规媒体文件。
但我真的很想知道:
- 如果 ExoPlayer 能够处理来自内存(字节数组、输入流或类似内容)的媒体(分段 mp4)?
- 如果是,哪种媒体来源是最好的选择?
更新
我在关注@Biscuit 的link。
我实现了自己的数据源:
public class MediaDispatcher implements DataSource {
public static final String LOG_TAG = "MediaDispatcher";
private DataSpec mDataSpec;
private String mBuffer;
@Override
public void addTransferListener(TransferListener transferListener) {
Log.d(LOG_TAG, "addTransferListener");
}
@Override
public long open(DataSpec dataSpec) throws IOException {
Log.d(LOG_TAG, "open");
mDataSpec = dataSpec;
return Long.MAX_VALUE;
}
@Override
public int read(byte[] buffer, int offset, int readLength) {
Log.d(LOG_TAG, "read, readLength=" + readLength);
if (0 == readLength) return 0;
if (readLength > mBuffer.length()) buffer = mBuffer.getBytes();
return mBuffer.length();
}
public void write(String buffer) throws InterruptedException {
//My service calls this
mBuffer = buffer;
}
@Nullable
@Override
public Uri getUri() {
Log.d(LOG_TAG, "getUri");
return Uri.EMPTY;
}
@Override
public void close() throws IOException {
Log.d(LOG_TAG, "close");
}
}
我正在像下面这样初始化它:
DataSource.Factory factory = new DataSource.Factory() {
@Override
public DataSource createDataSource() {
return new MediaDispatcher();
}
};
MediaSource mediaSource = new ExtractorMediaSource(mMediaDispatcher.getUri(),
factory, new DefaultExtractorsFactory(), null, null);
mplayer = new SimpleExoPlayer.Builder(context).build();
myVideoLayout.setPlayer(mplayer)
mplayer.prepare(mediaSource);
但我的问题是 ExoPlayer 一次只能读取 1 个字节!
日志:
getUri
addTransferListener
open
getUri
getUri
read, readLength=4
read, readLength=1
read, readLength=1
read, readLength=1
read, readLength=1
... (same line repeats)
close
另外,ExtractorMediaSource 已被弃用,所以我不知道如何继续。
我已经更新了初始化部分:
MediaSource mediaSource = new ProgressiveMediaSource.Factory(factory).createMediaSource(Uri.EMPTY);
但 ExoPlayer 仍然希望一次只读取 1 个字节。
【问题讨论】:
-
你找到解决办法了吗?
标签: android exoplayer exoplayer2.x