本文介绍了Exoplayer播放字节数组中的音频-ByteArrayDataSource的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Exoplayer,尝试播放字节数组中的音频文件.我正在尝试使用ByteArrayDataSource,但是在调用构造函数时出现错误: new ByteArrayDataSource(data); 这是我想出的代码:

Using Exoplayer, I'm trying to play an audio file from a byte array. I'm trying to use the ByteArrayDataSource, but am getting an error when calling the constructor: new ByteArrayDataSource(data);Here is the code I've come up with:

private void prepareExoPlayerFromByteArray(byte[] data){
        exoPlayer = ExoPlayerFactory.newSimpleInstance(this, new DefaultTrackSelector(null), new DefaultLoadControl());
        exoPlayer.addListener(eventListener);


        final ByteArrayDataSource byteArrayDataSource = new ByteArrayDataSource(data);

        /*
        DataSpec dataSpec = new DataSpec(byteArrayDataSource.getUri());
        try {
            byteArrayDataSource.open(dataSpec);
        } catch (IOException e) {
            e.printStackTrace();
        }
        */

        DataSource.Factory factory = new DataSource.Factory() {
            @Override
            public DataSource createDataSource() {
                return byteArrayDataSource;
            }
        };

        MediaSource audioSource = new ExtractorMediaSource(byteArrayDataSource.getUri(),
                factory, new DefaultExtractorsFactory(),null,null);
        exoPlayer.prepare(audioSource);
    }

我得到的错误是:

E/ExoPlayerImplInternal: Internal runtime error.
                                                                                java.lang.NullPointerException
                                                                                    at com.google.android.exoplayer2.util.Assertions.checkNotNull(Assertions.java:107)
                                                                                    at com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.<init>(ExtractorMediaPeriod.java:591)
                                                                                    at com.google.android.exoplayer2.source.ExtractorMediaPeriod.startLoading(ExtractorMediaPeriod.java:452)
                                                                                    at com.google.android.exoplayer2.source.ExtractorMediaPeriod.prepare(ExtractorMediaPeriod.java:165)
                                                                                    at com.google.android.exoplayer2.ExoPlayerImplInternal.maybeUpdateLoadingPeriod(ExoPlayerImplInternal.java:1260)
                                                                                    at com.google.android.exoplayer2.ExoPlayerImplInternal.updatePeriods(ExoPlayerImplInternal.java:1102)
                                                                                    at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:447)
                                                                                    at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:300)
                                                                                    at android.os.Handler.dispatchMessage(Handler.java:98)
                                                                                    at android.os.Looper.loop(Looper.java:234)
                                                                                    at android.os.HandlerThread.run(HandlerThread.java:61)
                                                                                    at com.google.android.exoplayer2.util.PriorityHandlerThread.run(PriorityHandlerThread.java:40)

错误似乎来自ByteArrayDataSource的构造函数,并说传递给它的数据为null,这不是我在调用它之前检查的,并且该数组中有14002427个字节.

The error seems to come from the constructor of ByteArrayDataSource and is saying that the data passed to it is null, which it isn't as I check before calling it and there are 14002427 bytes in that array.

/**
   * @param data The data to be read.
   */
  public ByteArrayDataSource(byte[] data) {
    Assertions.checkNotNull(data);
    Assertions.checkArgument(data.length > 0);
    this.data = data;
  }

我在做什么错了,我该如何解决?有没有人通过传递字节数组作为源来使用Exoplayer播放音频文件的有效示例?

推荐答案

class UriByteDataHelper {


        public Uri getUri(byte[] data) {

            try {
                URL url = new URL(null, "bytes:///" + "audio", new BytesHandler(data));
                return Uri.parse( url.toURI().toString());
            } catch (MalformedURLException e) {
                throw new RuntimeException(e);
            } catch (URISyntaxException e) {
                throw new RuntimeException(e);
            }

        }

        class BytesHandler extends URLStreamHandler {
            byte[] mData;
            public BytesHandler(byte[] data) {
                mData = data;
            }

            @Override
            protected URLConnection openConnection(URL u) throws IOException {
                return new ByteUrlConnection(u, mData);
            }
        }

        class ByteUrlConnection extends URLConnection {
            byte[] mData;
            public ByteUrlConnection(URL url, byte[] data) {
                super(url);
                mData = data;
            }

            @Override
            public void connect() throws IOException {
            }

            @Override
            public InputStream getInputStream() throws IOException {

                return new ByteArrayInputStream(mData);
            }
        }
    }



  private void prepareExoPlayerFromByteArray(byte[] data){
        exoPlayer = ExoPlayerFactory.newSimpleInstance(this, new DefaultTrackSelector(null), new DefaultLoadControl());
        exoPlayer.addListener(eventListener);

        final MByteArrayDataSource byteArrayDataSource = new MByteArrayDataSource(data);
        Log.i(TAG,"ByteArrayDataSource constructed.");
        Uri audioByteUri = new UriByteDataHelper().getUri(data);
        DataSpec dataSpec = new DataSpec(audioByteUri);
        try {
            byteArrayDataSource.open(dataSpec);
        } catch (IOException e) {
            e.printStackTrace();
        }


        DataSource.Factory factory = new DataSource.Factory() {
            @Override
            public DataSource createDataSource() {
                return byteArrayDataSource;
            }
        };
        Log.i(TAG,"DataSource.Factory constructed.");


        MediaSource audioSource = new ExtractorMediaSource(audioByteUri,
                factory, new DefaultExtractorsFactory(),null,null);
        Log.i(TAG,"Audio source constructed.");
        exoPlayer.prepare(audioSource);
        initMediaControls();
    }

这篇关于Exoplayer播放字节数组中的音频-ByteArrayDataSource的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-12 15:24