Je recherche un exemple/explication simple et efficace sur la façon d'implémenter ExoPlayer
pour HLS Adaptive
diffusion. Je suis un débutant et je n'ai pas d'expérience et de connaissances, je peux donc comprendre comment le faire à partir de l'exemple de code sur git.
Il y a trop de "pièces mobiles" pour que le débutant puisse le comprendre et le réutiliser dans ses propres projets.
Quelqu'un peut-il m'aider à apprendre et à comprendre comment utiliser/implémenter ExoPlayer
pour obtenir cette fonctionnalité?
Merci!
La façon la plus simple de commencer à utiliser ExoPlayer est de l'ajouter en tant que dépendance gradle. Vous devez vous assurer que le référentiel jcenter est inclus dans le fichier build.gradle à la racine de votre projet:
repositories { jcenter() }
Ensuite, incluez les éléments suivants dans le fichier build.gradle de votre module:
compile 'com.google.Android.exoplayer:exoplayer:r2.2.0'
1. Votre fichier de mise en page
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
Android:id="@+id/activity_main"
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<com.google.Android.exoplayer2.ui.SimpleExoPlayerView
Android:id="@+id/player_view"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:focusable="true"
app:resize_mode="fill"/>
<ProgressBar
Android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center"
Android:visibility="gone"/>
</FrameLayout>
2. Votre fichier de classe (activité)
public class VideoPlayerActivity extends AppCompatActivity implements ExoPlayer.EventListener {
private SimpleExoPlayerView simpleExoPlayerView;
private String hlsVideoUri = "http://playertest.longtailvideo.com/adaptive/bbbfull/bbbfull.m3u8";
private SimpleExoPlayer player;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_player);
// 1. Create a default TrackSelector
Handler mainHandler = new Handler();
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
// 2. Create a default LoadControl
LoadControl loadControl = new DefaultLoadControl();
// 3. Create the player
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);
simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);
simpleExoPlayerView.setPlayer(player);
// Measures bandwidth during playback. Can be null if not required.
DefaultBandwidthMeter defaultBandwidthMeter = new DefaultBandwidthMeter();
// Produces DataSource instances through which media data is loaded.
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this,
Util.getUserAgent(this, "Exo2"), defaultBandwidthMeter);
// Produces Extractor instances for parsing the media data.
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
// This is the MediaSource representing the media to be played.
HlsMediaSource hlsMediaSource = new HlsMediaSource(Uri.parse(hlsVideoUri), dataSourceFactory, mainHandler, new AdaptiveMediaSourceEventListener() {
@Override
public void onLoadStarted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs) {
}
@Override
public void onLoadCompleted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
}
@Override
public void onLoadCanceled(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded) {
}
@Override
public void onLoadError(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded, IOException error, boolean wasCanceled) {
}
@Override
public void onUpstreamDiscarded(int trackType, long mediaStartTimeMs, long mediaEndTimeMs) {
}
@Override
public void onDownstreamFormatChanged(int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaTimeMs) {
}
});
player.addListener(this);
player.prepare(hlsMediaSource);
simpleExoPlayerView.requestFocus();
player.setPlayWhenReady(true);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
}
@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.STATE_BUFFERING:
//You can use progress dialog to show user that video is preparing or buffering so please wait
progressBar.setVisibility(View.VISIBLE);
break;
case Player.STATE_IDLE:
//idle state
break;
case Player.STATE_READY:
// dismiss your dialog here because our video is ready to play now
progressBar.setVisibility(View.GONE);
break;
case Player.STATE_ENDED:
// do your processing after ending of video
break;
}
}
@Override
public void onPlayerError(ExoPlaybackException error) {
AlertDialog.Builder adb = new AlertDialog.Builder(VideoPlayerActivity.this);
adb.setTitle("Could not able to stream video");
adb.setMessage("It seems that something is going wrong.\nPlease try again.");
adb.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish(); // take out user from this activity. you can skip this
}
});
AlertDialog ad = adb.create();
ad.show();
}
@Override
public void onPositionDiscontinuity() {
}
@Override
protected void onPause() {
super.onPause();
if (player != null) {
player.setPlayWhenReady(false); //to pause a video because now our video player is not in focus
}
}
@Override
protected void onDestroy() {
super.onDestroy();
player.release();
}
}
Je pense que cela suffit pour les débutants. Gardez également à l'esprit que les composants audio et vidéo standard de cette bibliothèque reposent sur l'API MediaCodec d'Android, qui a été publiée dans Android 4.1 (API niveau 16). Cela ne fonctionnera donc pas sur Android 4.0 et inférieur.
N'oubliez pas d'ajouter cette autorisation au manifest file
:
<uses-permission Android:name="Android.permission.INTERNET"/>
La réponse de @Vicky fonctionnera, mais a un défaut.
Le compteur de bande passante que vous passez au sélecteur de piste doit être le même que celui utilisé par la fabrique de sources de données. La fabrique de sources de données maintient l'estimation de la bande passante en appelant les méthodes du compteur BW, et le processus de sélection de piste adaptative obtient l'estimation pour décider à quelle piste s'adapter.
S'ils ne sont pas la même instance, la sélection adaptative obtient toujours -1 comme BW et choisit une option intermédiaire.
Les applications de démonstration ExoPlayer ont également cette faille. Ils passent false à useBwMeter dans buildDataSource (), ce qui signifie aucune mise à jour de l'estimation BW EDIT: En fait, ce compteur BW est destiné au chargeur de manifestes. Il n'a pas besoin d'utiliser le compteur BW.