2017-12-11 26 views
0

Exoplayer, ExoMedia 또는 다른 플레이어를 사용하여 HLS 형식의 Vimeo 비디오에 포함 된 다른 자막을 활성화하고 선택하는 방법은 무엇입니까? iOS에서이 동일한 비디오는 이미 자막 옵션을 제공하지만 Android에서는 구현 방법을 찾을 수 없습니다.Exoplayer에 HLS 임베디드 캡션을 표시하는 방법

답변

0

내 대답은 this one과 많이 닮아 있으므로 먼저 확인해보십시오.

ExoPlayer는 Android 용으로 필요한 라이브러리입니다. 자막을 표시하는 것은 쉬운 일이 아니지만 해당 라이브러리의 demo app에는 HLS 비디오에서 작업하도록하는 데 필요한 모든 코드가 있습니다. 더 구체적으로는 PlayerActivity 클래스입니다. 데모 앱에서 HLS -> "Apple 16x9 기본 스트림"으로 이동할 수 있습니다.이 비디오에는 대용량의 자막이 있습니다 (일명 "텍스트 트랙").

도우미에 의존하지 않도록 코드를 단순화하기 만하면 어떻게 작동하는지 볼 수 있습니다. 자막에 대해서는입니다. 아래 코드 중 일부를 작성하고 문서화했습니다. 당신이 그들의 initializePlayer() 방법의 끝 부분에 다음 코드를 게시 할 경우

private static class ClosedCaptionManager { 

    ClosedCaptionManager(MappingTrackSelector mappingTrackSelector, SimpleExoPlayer player) { 
     this.player = player; 
     this.trackSelector = mappingTrackSelector; 
    } 

    SimpleExoPlayer player; 
    MappingTrackSelector trackSelector; 

    // These two could be fields OR passed around 
    int textTrackIndex; 
    TrackGroupArray trackGroups; 

    ArrayList<Pair<Integer, Integer>> pairTrackList = new ArrayList<>(); 

    private boolean checkAndSetClosedCaptions() { 
     // This is the body of the logic for see if there are even video tracks 
     // It also does some field setting 
     MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo(); 
     if (mappedTrackInfo == null) { 
      return false; 
     } 
     for (int i = 0; i < mappedTrackInfo.length; i++) { 
      trackGroups = mappedTrackInfo.getTrackGroups(i); 
      if (trackGroups.length != 0) { 
       switch (player.getRendererType(i)) { 
        case C.TRACK_TYPE_TEXT: 
         textTrackIndex = i; 
         return true; 
       } 
      } 
     } 
     return false; 
    } 

    private void buildTrackList() { 
     // This next part is actually about getting the list. 
     // Below you'd be building up items in a list. This just does 
     // views directly, but you could just have a list of track names (with indexes) 
     for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) { 
      TrackGroup group = trackGroups.get(groupIndex); 
      for (int trackIndex = 0; trackIndex < group.length; trackIndex++) { 
       if (trackIndex == 0) { 
        // Beginning of a new set, the demo app adds a divider 
       } 
       //CheckedTextView trackView = ...; // The TextView to show in the list 
       // The below points to a util which extracts the quality from the TrackGroup 
       //trackView.setText(DemoUtil.buildTrackName(group.getFormat(trackIndex))); 
       Log.e("Thing", DemoUtil.buildTrackName(group.getFormat(trackIndex))); 
       pairTrackList.add(new Pair<>(groupIndex, trackIndex)); 
      } 
     } 
    } 

    private void onTrackViewClick(Pair<Integer, Integer> trackPair) { 
     // Assuming you tagged the view with the groupIndex and trackIndex, you 
     // can build your override with that info. 
     Pair<Integer, Integer> tag = trackPair; 
     int groupIndex = tag.first; 
     int trackIndex = tag.second; 
     // This is the override you'd use for something that isn't adaptive. 
     // `override = new SelectionOverride(FIXED_FACTORY, groupIndex, trackIndex);` 
     // Otherwise they call their helper for adaptives (HLS/DASH), which roughly does: 
     int[] tracks = getTracksAdding(new MappingTrackSelector.SelectionOverride(
         new FixedTrackSelection.Factory(), groupIndex, trackIndex), 
       trackIndex 
     ); 
     TrackSelection.Factory factory = tracks.length == 1 
       ? new FixedTrackSelection.Factory() 
       : new AdaptiveTrackSelection.Factory(BANDWIDTH_METER); 

     MappingTrackSelector.SelectionOverride override = 
       new MappingTrackSelector.SelectionOverride(factory, groupIndex, tracks); 

     // Then we actually set our override on the selector to switch the text track 
     trackSelector.setSelectionOverride(textTrackIndex, trackGroups, override); 
    } 

    private static int[] getTracksAdding(MappingTrackSelector.SelectionOverride override, int addedTrack) { 
     int[] tracks = override.tracks; 
     tracks = Arrays.copyOf(tracks, tracks.length + 1); 
     tracks[tracks.length - 1] = addedTrack; 
     return tracks; 
    } 
} 

그렇다면, 당신은이 조각을 함께 맞는 방법에 대한 아이디어를 얻을 수 있습니다.

final ClosedCaptionManager closedCaptionManager = new ClosedCaptionManager(trackSelector, player); 

    new Handler().postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      boolean hasTracks = closedCaptionManager.checkAndSetClosedCaptions(); 
      if (hasTracks) { 
       closedCaptionManager.buildTrackList(); 
       closedCaptionManager.onTrackViewClick(closedCaptionManager.pairTrackList.get(4)); 
      } 
     } 
    }, 2000); 

위의 코드는 상당히 엉성하지 만, 적어도 올바른 방향으로 시작해야합니다. 필자가 작성한 것을 사용하는 것을 권장하지는 않습니다. 다른 조각들이 어떻게 어울리는 지 아이디어를 얻는 것이 대부분입니다. 데모 응용 프로그램에서 가지고있는 코드는 비디오, 오디오 및 텍스트 트랙을 가질 수 있기 때문에 코드가 다른 트랙 선택 유형에 대해 매우 재사용 할 수 있다는 점에서 조금 낫습니다.