我当前正在创建一个应用程序,该应用程序从API获取视频列表,然后使用ExoPlayer
顺序播放。昨天,一切正常,但现在我无法播放视频。播放器尝试播放视频,但卡在缓冲状态。
为了确保我们服务器上的视频不是我的应用无法正常运行的原因,我在线查找了一个mp4视频示例,并发现this。它仍然没有播放。其他SO问题的答案也不起作用。
这是我用于初始化ExoPlayer
的代码。如果您需要这些信息,我正在使用PlayerView
。
private void initializePlayer() {
if (exoPlayer == null) {
mainHandler = new Handler();
bandwidthMeter = new DefaultBandwidthMeter();
trackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
trackSelector = new DefaultTrackSelector(trackSelectionFactory);
LoadControl loadControl = new DefaultLoadControl();
exoPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);
playerView.setPlayer(exoPlayer);
exoPlayer.addListener(exoPlayEventListener);
}
}
这是EventListener
的代码。
Player.EventListener exoPlayEventListener = new Player.EventListener() {
@Override
public void onTimelineChanged(Timeline timeline, @Nullable Object manifest, int reason) {
}
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
@Override
public void onLoadingChanged(boolean isLoading) {
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState){
case Player.DISCONTINUITY_REASON_PERIOD_TRANSITION:
Log.d(TAG, "eventListen onPlayerStateChanged DISCONTINUITY_REASON_PERIOD_TRANSITION");
break;
case Player.STATE_BUFFERING:
Log.d(TAG, "Buffering . . . .");
break;
case Player.STATE_READY:
Log.d(TAG, "Ready!!!");
break;
case Player.STATE_ENDED:
Log.d(TAG, "player ended");
playLoopVideo();
break;
}
}
@Override
public void onRepeatModeChanged(int repeatMode) {
}
@Override
public void onPlayerError(ExoPlaybackException error) {
switch (error.type) {
case ExoPlaybackException.TYPE_SOURCE:
Log.d(TAG, "ERR TYPE_SOURCE: " + error.getSourceException().getMessage());
playLoopVideo();
break;
case ExoPlaybackException.TYPE_RENDERER:
Log.d(TAG, "ERR TYPE_RENDERER: " + error.getRendererException().getMessage());
playLoopVideo();
break;
case ExoPlaybackException.TYPE_UNEXPECTED:
Log.d(TAG, "ERR TYPE_UNEXPECTED: " + error.getUnexpectedException().getMessage());
playLoopVideo();
break;
}
}
@Override
public void onPositionDiscontinuity(int reason) {
if (reason == Player.DISCONTINUITY_REASON_PERIOD_TRANSITION) {
}
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
};
这是我用来更改视频播放的代码。从API获取视频列表后,我会调用它。
private void playLoopVideo() {
toPlayVidIndex = playedVidIndex;
String toPlayVidURL = "";
if(playedVidIndex == 7 && !isDefaultPlayed){
toPlayVidURL = defaultUrl;
playedVidIndex--;
isDefaultPlayed = true;
}else{
if (playedVidIndex >= vidArrLst.size()){
playedVidIndex = 0;
toPlayVidIndex = playedVidIndex;
}
toPlayVidURL = vidArrLst.get(toPlayVidIndex).getUrl();
isDefaultPlayed = false;
}
startStream(toPlayVidURL);
playedVidIndex++;
}
这是播放视频流的代码。
private void startStream(String streamLink){
Uri mediaUri = Uri.parse(streamLink);
DefaultBandwidthMeter defaultBandwidthMeter = new DefaultBandwidthMeter();
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(ctx.getApplicationContext(),
Util.getUserAgent(ctx.getApplicationContext(),
"Streamer"), defaultBandwidthMeter);
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(mediaUri);
exoPlayer.setPlayWhenReady(true);
exoPlayer.prepare(mediaSource, true, false);
currentStreamMediaSource = mediaSource;
}
在onStop()
和onDestroy()
中,我将此代码称为释放播放器。
private void releasePlayer() {
if (exoPlayer != null) {
playbackPosition = exoPlayer.getCurrentPosition();
currentWindow = exoPlayer.getCurrentWindowIndex();
playWhenReady = exoPlayer.getPlayWhenReady();
exoPlayer.release();
exoPlayer = null;
}
}
如果需要,这是我的build.gradle(app)。
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "biz.net.com.streamer"
minSdkVersion 17
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.google.android.exoplayer:exoplayer:2.9.1'
implementation 'com.android.volley:volley:1.1.1'
}
更新:
今天,我尝试使用startStream方法直接播放视频,并且播放了示例mp4视频和来自我们服务器的视频。
这是我用于获取本地视频API的代码。由于某些原因,如果我使用该方法播放视频,它将无法播放,但直接使用startStream()可以播放视频。
public void getVideoAds(String serverURL){
String url = "http://"+serverURL+"/video/";
StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.d(TAG, "getVidAds res: "+response);
try {
JSONObject jsonObj = new JSONObject(response);
JSONObject defaultObj = jsonObj.getJSONObject("default");
JSONArray videoObj = jsonObj.getJSONArray("videos");
defaultUrl = defaultObj.getString("url");
for (int i = 0; i < videoObj.length(); i++){
JSONObject video = videoObj.getJSONObject(i);
VideoAd v = new VideoAd();
v.setName(getVideoNameFromLink(video.getString("url")));
v.setUrl(video.getString("url"));
v.setVideoId(video.getInt("id"));
v.setVersion(video.getInt("version"));
v.setLocalPath("");
vidArrLst.add(v);
}
playLoopVideo();
} catch (Exception e) {
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "getVidAds err: " + error.getMessage());
}
});
queue.add(stringRequest);
}
更新:
您好,我又问了一个here问题,关于Volley有时如何无法正常工作,[有点怪异]影响ExoPlayer
停留在BUFFERING状态。如果您想了解更多信息,请查看另一个问题,因为我不想重复我在此处发布的所有内容。