Le SDK ApsaraVideo Player prend en charge l'ajout, l'analyse et le rendu de flux de sous-titres externes aux formats WebVTT, SRT et ASS, ainsi que les flux de sous-titres intégrés dans les fichiers M3U8. Cette rubrique décrit l'implémentation sur Android et iOS.
Pour obtenir le code complet et les détails d'implémentation, reportez-vous au projet API-Example et suivez ses bonnes pratiques.
Consultez le code source du module ExternalSubtitle dans les projets API-Example-Android et API-Example-iOS.
Limites
Seuls les fichiers de sous-titres externes aux formats WebVTT, SRT et ASS sont pris en charge.
Exemple de rendu
Pour empaqueter les flux de sous-titres en vue de leur rendu, consultez Bonnes pratiques pour le transcodage et l'empaquetage multi-sous-titres.
Implémentation clé sur Android
Rendre les sous-titres externes
-
Importez les bibliothèques de dépendance.
import com.aliyun.subtitle.SubTitleBase; import com.cicada.player.utils.webVtt.VttSubtitleView; import com.aliyun.player.IPlayer; -
Définissez la vue d'affichage.
vttSubtitleView = new VttSubtitleView(getContext()); vttSubtitleView.setId(R.id.cicada_player_vtt_subtitle); // Set the display position of the subtitles. Add them to the center of the layout. FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT ); params.gravity = Gravity.CENTER; // Add to the center of the layout. // Add the VTT subtitle view to the root layout view. mRootFrameLayout.addView(mVttSubtitleView, params); -
Définissez les écouteurs.
// In the following example, mVideoListPlayer is a listPlayer. The process is the same if you use aliPlayer. // 1. Set OnSubtitleDisplayListener. mVideoListPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() { @Override public void onSubtitleExtAdded(int trackIndex, String url) { // Because we are only testing the addition of a single VTT file, select the subtitle track directly after the VTT file is added. mVideoListPlayer.selectExtSubtitle(trackIndex, true); } @Override public void onSubtitleShow(int trackIndex, long id, String data) { if (vttSubtitleView != null) { vttSubtitleView.show(id, data); } } @Override public void onSubtitleHide(int trackIndex, long id) { if (vttSubtitleView != null) { vttSubtitleView.dismiss(id); } } @Override public void onSubtitleHeader(int trackIndex, String header) { if (vttSubtitleView != null) { vttSubtitleView.setVttHeader(header); } } }); // 2. Set VideoSizeChangedListener. This is a required step. The data must be passed back to vttSubtitleView. mVideoListPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() { @Override public void onVideoSizeChanged(int width, int height) { int viewWidth = getWidth(); int viewHeight = getHeight(); IPlayer.ScaleMode mode = mVideoListPlayer.getScaleMode(); SubTitleBase.VideoDimensions videoDimensions = SubTitleBase.getVideoDimensionsWhenRenderChanged(width, height, viewWidth, viewHeight, mode); vttSubtitleView.setVideoRenderSize(videoDimensions.videoDisplayWidth, videoDimensions.videoDisplayHeight); } }); -
Après l'exécution de l'opération
prepare/moveTo/moveToNext/moveToPrevpar le lecteur, effacez la vue d'affichage.source = getSource(someParams); // pseudocode mVideoListPlayer.moveTo(mCurrentUUID + ""); if (vttSubtitleView != null) { vttSubtitleView.clearAll(); } if (!source.getExtSubtitleUrl().isEmpty()) { mCurrentExtSubtitle = source.getExtSubtitleUrl(); // Get the external subtitle URL. } -
Une fois le rappel
onPrepareddu lecteur déclenché, ajoutez le fichier de sous-titres.// Currently, you can call addExtSubtitle only after the player's onPrepared callback is invoked. mVideoListPlayer.addExtSubtitle(mCurrentExtSubtitle);
Rendre les sous-titres empaquetés au format M3U8
Ne rendez pas simultanément les sous-titres empaquetés au format M3U8 et les sous-titres externes.
-
Importez les bibliothèques de dépendance.
import com.aliyun.subtitle.SubTitleBase; import com.cicada.player.utils.webVtt.VttSubtitleView; import com.aliyun.player.IPlayer; -
Définissez la vue d'affichage.
vttSubtitleView = new VttSubtitleView(getContext()); vttSubtitleView.setId(R.id.cicada_player_vtt_subtitle); // Set the display position of the subtitles. Add them to the center of the layout. FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT ); params.gravity = Gravity.CENTER; // Add to the center of the layout. // Add the VTT subtitle view to the root layout view. mRootFrameLayout.addView(mVttSubtitleView, params); -
Définissez les écouteurs.
// In the following example, mVideoListPlayer is a listPlayer. The process is the same if you use aliPlayer. // 1. Set OnSubtitleDisplayListener. mVideoListPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() { @Override public void onSubtitleExtAdded(int trackIndex, String url) { // Because we are only testing the addition of a single VTT file, select the subtitle track directly after the VTT file is added. mVideoListPlayer.selectExtSubtitle(trackIndex, true); } @Override public void onSubtitleShow(int trackIndex, long id, String data) { if (vttSubtitleView != null) { vttSubtitleView.show(id, data); } } @Override public void onSubtitleHide(int trackIndex, long id) { if (vttSubtitleView != null) { vttSubtitleView.dismiss(id); } } @Override public void onSubtitleHeader(int trackIndex, String header) { if (vttSubtitleView != null) { vttSubtitleView.setVttHeader(header); } } }); // 2. Set VideoSizeChangedListener. This is a required step. The data must be passed back to vttSubtitleView. mVideoListPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() { @Override public void onVideoSizeChanged(int width, int height) { int viewWidth = getWidth(); int viewHeight = getHeight(); IPlayer.ScaleMode mode = mVideoListPlayer.getScaleMode(); SubTitleBase.VideoDimensions videoDimensions = SubTitleBase.getVideoDimensionsWhenRenderChanged(width, height, viewWidth, viewHeight, mode); vttSubtitleView.setVideoRenderSize(videoDimensions.videoDisplayWidth, videoDimensions.videoDisplayHeight); } }); -
Après l'exécution de l'opération
prepare/moveTo/moveToNext/moveToPrevpar le lecteur, effacez la vue d'affichage.source = getSource(someParams); // pseudocode mVideoListPlayer.moveTo(mCurrentUUID + ""); if (vttSubtitleView != null) { vttSubtitleView.clearAll(); } if (!source.getExtSubtitleUrl().isEmpty()) { mCurrentExtSubtitle = source.getExtSubtitleUrl(); // Get the external subtitle URL. } -
Définissez le rappel
onTrackReadypour récupérer les informations sur les sous-flux.mAliPlayer.setOnTrackReadyListener(new IPlayer.OnTrackReadyListener() { @Override public void onTrackReady(MediaInfo mediaInfo) { List<TrackInfo> trackInfos = mediaInfo.getTrackInfos(); for (TrackInfo trackInfo : trackInfos) { if (trackInfo.getType() == TrackInfo.Type.TYPE_SUBTITLE) { // TODO } } } }); -
Une fois le rappel
onPrepareddu lecteur déclenché, appelezselectTrackpour changer de piste de sous-titres.// index is the TrackIndex of the target subtitle stream. mAliPlayer.selectTrack(index);
Implémentation clé sur iOS
Rendre les sous-titres externes
-
Définissez le rappel.
/** @brief An external subtitle is added. @param player The player pointer. @param trackIndex The index of the subtitle track to be displayed. @param URL The subtitle URL. */ - (void)onSubtitleExtAdded:(AliPlayer*)player trackIndex:(int)trackIndex URL:(NSString *)URL { NSLog(@"onSubtitleExtAdded: %@, trackIndex: %d", URL, trackIndex); [self.listPlayer selectExtSubtitle:trackIndex enable:YES]; } -
Une fois le rappel
onPrepareddu lecteur déclenché, ajoutez le fichier de sous-titres.if (self.currentModel.extSubtitleUrl != Nil) { [self.listPlayer addExtSubtitle:self.currentModel.extSubtitleUrl]; }
Rendre les sous-titres empaquetés au format M3U8
Ne rendez pas simultanément les sous-titres empaquetés au format M3U8 et les sous-titres externes.
-
Définissez le rappel.
/** @brief An external subtitle is added. @param player The player pointer. @param trackIndex The index of the subtitle track to be displayed. @param URL The subtitle URL. */ - (void)onSubtitleExtAdded:(AliPlayer*)player trackIndex:(int)trackIndex URL:(NSString *)URL { NSLog(@"onSubtitleExtAdded: %@, trackIndex: %d", URL, trackIndex); [self.listPlayer selectExtSubtitle:trackIndex enable:YES]; } -
Définissez le rappel
onTrackReadypour récupérer les informations sur les sous-flux.- (void)onTrackReady:(AliPlayer*)player info:(NSArray<AVPTrackInfo*>*)info { // } -
Une fois le rappel
prepare donedu lecteur déclenché, appelezselectTrackpour changer de piste de sous-titres.// index is the TrackIndex of the target subtitle stream. [self.player selectTrack:index];
Implémenter un rendu personnalisé basé sur les flux WebVTT
ApsaraVideo Player analyse et rend les flux WebVTT standard sur Android et iOS. Le lecteur lit les styles CSS pour produire un rendu uniforme des sous-titres sur toutes les plateformes et prend en charge plusieurs styles de texte dans un seul fichier, ce qui s'avère utile pour distinguer les dialogues des personnages, mettre en évidence le contenu clé et créer des effets visuels spéciaux.
L'exemple suivant montre la structure d'un fichier WebVTT :
REGION : définit la zone d'affichage.
STYLE : définit le style de police. Le premier élément correspond au style par défaut.
WEBVTT
REGION
id:bottom
width:70.000000%
lines:3
viewportanchor:15.000000%,95.000000%
regionanchor:0.000000%,100.000000%
scroll:up
STYLE
::cue {
color: white;
font-size: 70%;
font-family: Noto Sans;
font-weight: bold;
background-color: rgba(0, 0, 0, 0.2);
}
::cue(.font1) {
color: rgba(255, 255, 255, 1);
font-weight: bold;
font-family: Noto Sans;
outline-width: 3px;
outline-color: rgba(0, 0, 0, 1);
}
::cue(.font2) {
color: rgba(252, 255, 101, 1);
font-style: bold;
font-family: Noto Sans;
outline-width: 3px;
outline-color: rgba(0, 0, 0, 1);
}
::cue(.font3) {
color: rgba(255, 191 23, 1);
font-style: bold;
font-family: Noto Sans;
outline-width: 3px;
outline-color: rgba(183, 28, 28, 1);
}
00:00:00.200 --> 00:00:01.800 region:bottom align:center
Defendant Bo Hanshi
00:00:01.800 --> 00:00:03.200 region:bottom align:center
Do you have anything else to say
00:00:04.100 --> 00:00:04.800 region:bottom align:center
I
00:00:11.200 --> 00:00:12.200 region:bottom align:center
<v.font1>I have nothing to say</v.font1>
00:00:14.500 --> 00:00:16.200 region:bottom align:center
Defendant Bo Hanshi
...
Pour appliquer un style à un segment de texte spécifique, utilisez la syntaxe suivante :
<v.font1>I have nothing to say</v.font1>