Exoplayer - 是否可以在加载之前检查 URL 是否有效 mp4/webm url?

Exoplayer - Is it possible to check if a URL is a valid mp4/webm url before loading it?

是否可以在尝试加载播放器之前检查它是否真的是 URL 可以加载的播放器?

String mUrl = " --- ";
player = new SimpleExoPlayer.Builder(this).build();
       
        playerView.setPlayer(player);

        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
                Util.getUserAgent(this, "yourApplicationName"));
        Uri uri = Uri.parse(mUrl);

        MediaSource videoSource =
                new ProgressiveMediaSource.Factory(dataSourceFactory)
                        .createMediaSource(uri);
        player.prepare(videoSource);

或者是否有图书馆可以做到这一点?

为什么不直接使用 Exoplayer?

    private void checkIfMediaValid(String url, MediaValidationCallback mediaValidationCallback){
        SimpleExoPlayer player = new SimpleExoPlayer.Builder(this).build();

        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
                Util.getUserAgent(this, "yourApplicationName"));
        Uri uri = Uri.parse(url);

        MediaSource videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
                .createMediaSource(uri);
        player.prepare(videoSource);
        player.addListener(new Player.EventListener() {
            
            boolean listen = true;
            
            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
                if(!listen)
                    return;
                if(playbackState== Player.STATE_IDLE){
                    ExoPlaybackException error = player.getPlaybackError();
                    if(error!=null){
                        if (error.type == ExoPlaybackException.TYPE_SOURCE) {
                            IOException cause = error.getSourceException();
                            if (cause instanceof HttpDataSource.HttpDataSourceException) {// An HTTP error occurred.
                                HttpDataSource.HttpDataSourceException httpError = (HttpDataSource.HttpDataSourceException) cause;
                                if (httpError instanceof HttpDataSource.InvalidResponseCodeException) {//RESPONSE CODE NOT 2XX
                                    callback(false);
                                } else {
                                    Throwable throwable = httpError.getCause();
                                    if(throwable instanceof UnknownHostException){//NO NETWORK
                                        //callback(false);
                                    }
                                }
                            }else if(cause instanceof FileDataSource.FileDataSourceException){//NOT FOUND (PROBABLY INVALID URL)
                                callback(false);
                            }else if(cause instanceof UnrecognizedInputFormatException){//WRONG INPUT(CONTENT)
                                callback(false);
                            }else if(cause instanceof Loader.UnexpectedLoaderException){
                                Throwable throwable = cause.getCause();
                                if(throwable instanceof SecurityException){//PROBABLY PERMISSION DENIED (Internet or ...)
                                    //callback(false);
                                }
                            }
                        }
                    }
                    if(listen){//NO CALLBACK
                        listen = false;
                        player.release();
                    }
                }else if(playbackState == Player.STATE_READY){
                    callback(true);
                }
            }

            private void callback(boolean result){
                mediaValidationCallback.result(result);
                listen = false;
                player.release();
            }
        });
    }

    interface MediaValidationCallback{
        void result(boolean isValid);
    }

然后:

checkIfMediaValid(" --- ", isValid -> {
    //isValid : false
});

解决此问题的一种方法是检查您尝试加载的 URL 的扩展名。例如,URL: http://thisisavideo/randompath/random_id.mp4 很可能指向 mp4 资源。但是,这种方法有两个主要问题:

  1. 您不能指望 URL-extension。 http://simpleurlhaha.com 也可能指向 mp4 资源。
  2. 此方法不保证 URL 有效。



但是,一种保证有效的方法 是执行HTTP Head request on the URL and check the Content-Type. You can achieve this with Retrofit 或您正在使用的任何其他网络库。如果 URL 有效,您将收到类似这样的响应:

HTTP/1.1 200 OK
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Accept-Ranges: bytes
Content-Length: 1034745
Content-Type: video/mp4
Date: Wed, 17 Sat 2020 13:01:19 GMT
Last-Modified: Fri, 8 Aug 2019 21:12:31 GMT
Server: Apache

如您所见,只需在 Content-Type 字段上执行 if-check 即可检测它是 MP4 还是 WebM URL。

就我个人而言,我认为上述建议代价高昂,因为它涉及进行额外的网络调用,这会增加整体处理时间。如果这仍然适合您的use-case。请继续。