【问题标题】:Android: ExoPlayer direct feed raw mp4 (h264) fragmentsAndroid:ExoPlayer 直接提供原始 mp4 (h264) 片段
【发布时间】:2020-04-12 18:37:34
【问题描述】:

我正在研究 Android 在应用程序中显示 H264 视频的可能性。

视频流位于 mp4 容器内,可作为字节数组以逐块方式使用。

(我也可以使用MediaCodec,但我不想搞乱时间。)

我现在正在研究 ExoPlayer,但我对如何将 mp4 片段输入其中有点困惑:

MediaSources:

  • DASH 的 DashMediaSource。
  • 用于 SmoothStreaming 的 SsMediaSource。
  • 用于 HLS 的 HlsMediaSource。
  • ProgressiveMediaSource 用于常规媒体文件。

但我真的很想知道:

  1. 如果 ExoPlayer 能够处理来自内存(字节数组、输入流或类似内容)的媒体(分段 mp4)?
  2. 如果是,哪种媒体来源是最好的选择?

更新

我在关注@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


【解决方案1】:
  1. 没有简单的方法可以做到这一点,但您仍然可以使用ByteArrayDataSourceDataSourceInputStream。您也可以在 github 上查看他们的问题,有人发了 custom inputStream,这可能对您有用。

  2. 播放 MP4 文件需要ProgressiveMediaSource

【讨论】:

  • 我更新了我的帖子,请看一下,我无法继续
  • 您的用例似乎非常具体,您可能想在他们的 github 上打开一个问题,他们的回答很快。
猜你喜欢
  • 2014-06-14
  • 2016-07-10
  • 1970-01-01
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 2013-10-18
  • 2020-08-12
  • 2018-03-18
相关资源
最近更新 更多