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 资源。但是,这种方法有两个主要问题:
- 您不能指望 URL-extension。
http://simpleurlhaha.com
也可能指向 mp4 资源。
- 此方法不保证 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。请继续。
是否可以在尝试加载播放器之前检查它是否真的是 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 资源。但是,这种方法有两个主要问题:
- 您不能指望 URL-extension。
http://simpleurlhaha.com
也可能指向 mp4 资源。 - 此方法不保证 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。请继续。