2015-11-26 51 views
1

我在Android的流式視頻播放器中工作,需要顯示此流的字幕(當它們存在時),並且還顯示用戶選擇流中呈現的音頻頻道之一的方式。 我正在從Android MediaPlayer切換到VlcLib,以便能夠做到這一點。 但我找不到有關如何做到這一點的任何示例。如何在視頻流中使用vlc lib for Android選擇音頻頻道和字幕?

有沒有人已經這樣做?你可以分享一些例子或顯示線索嗎?

非常感謝您的幫助。

我的代碼,至極基於在互聯網上找到的例子是:

package com.wass08.vlcsimpleplayer; 

import com.wass08.vlcsimpleplayer.util.SystemUiHider; 

import android.annotation.TargetApi; 
import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.DialogInterface; 
import android.content.pm.ActivityInfo; 
import android.content.res.Configuration; 
import android.graphics.PixelFormat; 
import android.os.Build; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.util.DisplayMetrics; 
import android.util.Log; 
import android.view.Gravity; 
import android.view.MotionEvent; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.Window; 
import android.view.WindowManager; 
import android.widget.FrameLayout; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.ScrollView; 
import android.widget.SeekBar; 
import android.widget.TextView; 
import android.widget.Toast; 

import org.videolan.libvlc.EventHandler; 
import org.videolan.libvlc.IVideoPlayer; 
import org.videolan.libvlc.LibVLC; 
import org.videolan.libvlc.Media; 
import org.videolan.libvlc.MediaList; 

import java.lang.ref.WeakReference; 
import java.util.ArrayList; 
import java.util.Map; 

/** 
* An example full-screen activity that shows and hides the system UI (i.e. 
* status bar and navigation/system bar) with user interaction. 
* 
* @see SystemUiHider 
*/ 
public class FullscreenVlcPlayer extends Activity implements SurfaceHolder.Callback, IVideoPlayer 
{ 
    private String urlToStream; 

    // Display Surface 
    private LinearLayout vlcContainer; 
    private SurfaceView mSurface; 
    private SurfaceView mSubtitlesSurface; 
    private SurfaceHolder holder; 
    private SurfaceHolder mSubtitlesSurfaceHolder; 

    // Overlay/Controls 
    private FrameLayout vlcOverlay; 
    private ImageView vlcButtonPlayPause; 
    private Handler handlerOverlay; 
    private Runnable runnableOverlay; 
    private Handler handlerSeekbar; 
    private Runnable runnableSeekbar; 
    private SeekBar vlcSeekbar; 
    private TextView vlcDuration; 
    private TextView overlayTitle; 

    // media player 
    private LibVLC libvlc; 
    private int mVideoWidth; 
    private int mVideoHeight; 
    private final static int VideoSizeChanged = -1; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 

     // Retrieve our url 
     Bundle b = getIntent().getExtras(); 
     urlToStream = b.getString("url", null); 

     // HIDE THE ACTION BAR 
     getActionBar().hide(); 

     // SETUP THE UI 
     setContentView(R.layout.activity_fullscreen_vlc_player); 

     // VLC 
     vlcContainer = (LinearLayout) findViewById(R.id.vlc_container); 
     mSurface = (SurfaceView) findViewById(R.id.vlc_surface); 

     mSubtitlesSurface = (SurfaceView) findViewById(R.id.subtitles_surface); 

     // OVERLAY/CONTROLS 
     vlcOverlay = (FrameLayout) findViewById(R.id.vlc_overlay); 
     vlcButtonPlayPause = (ImageView) findViewById(R.id.vlc_button_play_pause); 
     vlcSeekbar = (SeekBar) findViewById(R.id.vlc_seekbar); 
     vlcDuration = (TextView) findViewById(R.id.vlc_duration); 

     overlayTitle = (TextView) findViewById(R.id.vlc_overlay_title); 
     overlayTitle.setText(urlToStream); 

     // AUTOSTART 
     playMovie(); 
    } 

    private void setSubtitles() 
    { 
     /* Only show the subtitles surface when using "Full Acceleration" mode */ 
     //if (libvlc.getHardwareAcceleration() == 2) 
     //{ 
      mSubtitlesSurface.setVisibility(View.VISIBLE); 
     //} 

     Map<Integer, String> mSubtitleTracksList; 
     Map<Integer, String> mAudioTracksList; 

     int numSubtitleTracks = libvlc.getSpuTracksCount(); 
     int numAudioTracks = libvlc.getAudioTracksCount(); 

     mSubtitleTracksList = libvlc.getSpuTrackDescription(); 
     mAudioTracksList = libvlc.getAudioTrackDescription(); 

     if (mSubtitleTracksList != null && mSubtitleTracksList.size() > 0) 
     { 

     } 

     if (mAudioTracksList != null && mAudioTracksList.size() > 0) 
     { 

     } 

     Log.d("LIBVLC_PLAYER", "Number of Subtitles Tracks = " + numSubtitleTracks); 
     Log.d("LIBVLC_PLAYER", "Number of Audio Tracks = " + numAudioTracks); 

     int i = 0; 

     for (Map.Entry<Integer, String> entry : mSubtitleTracksList.entrySet()) 
     { 
      Log.d("LIBVLC_PLAYER", "Subtitle Track " + i + " = " + entry.getValue().toString()); 
      i++; 
     } 

     libvlc.setSpuTrack(0); 

     i = 0; 

     for (Map.Entry<Integer, String> entry2 : mAudioTracksList.entrySet()) 
     { 
      Log.d("LIBVLC_PLAYER", "Audio Track " + i + " = " + entry2.getValue().toString()); 
      i++; 
     } 

     libvlc.setAudioTrack(0); 
    } 

    private final SurfaceHolder.Callback mSubtitlesSurfaceCallback = new SurfaceHolder.Callback() 
    { 
     @Override 
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 
     { 
      if (libvlc != null) 
      { 
       libvlc.attachSubtitlesSurface(holder.getSurface()); 
       Log.d("LIBVLC_PLAYER", "SurfaceHolder.Callback: width: " + width + " height: " + height); 
      } 
     } 

     @Override 
     public void surfaceCreated(SurfaceHolder holder) 
     { 
      Log.d("LIBVLC_PLAYER", "SurfaceHolder.Callback -> surfaceCreated"); 
     } 

     @Override 
     public void surfaceDestroyed(SurfaceHolder holder) 
     { 
      libvlc.detachSubtitlesSurface(); 
      Log.d("LIBVLC_PLAYER", "SurfaceHolder.Callback -> surfaceDestroyed"); 
     } 
    }; 

    private void showOverlay() 
    { 
     vlcOverlay.setVisibility(View.VISIBLE); 
    } 

    private void hideOverlay() 
    { 
     vlcOverlay.setVisibility(View.GONE); 
    } 

    private void setupControls() 
    { 
     getActionBar().hide(); 
     // PLAY PAUSE 
     vlcButtonPlayPause.setOnClickListener(
       new View.OnClickListener() 
       { 
        @Override 
        public void onClick(View view) 
        { 
         if (libvlc.isPlaying()) 
         { 
          libvlc.pause(); 
          vlcButtonPlayPause.setImageDrawable(getResources().getDrawable(R.drawable.ic_action_play_over_video)); 
         } 
         else 
         { 
          libvlc.play(); 
          vlcButtonPlayPause.setImageDrawable(getResources().getDrawable(R.drawable.ic_action_pause_over_video)); 
         } 
        } 
       } 
     ); 

     // SEEKBAR 
     handlerSeekbar = new Handler(); 
     runnableSeekbar = new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       if (libvlc != null) 
       { 
        long curTime = libvlc.getTime(); 
        long totalTime = (long) (curTime/libvlc.getPosition()); 
        int minutes = (int) (curTime/(60 * 1000)); 
        int seconds = (int) ((curTime/1000) % 60); 
        int endMinutes = (int) (totalTime/(60 * 1000)); 
        int endSeconds = (int) ((totalTime/1000) % 60); 
        String duration = String.format("%02d:%02d/%02d:%02d", minutes, seconds, endMinutes, endSeconds); 
        vlcSeekbar.setProgress((int) (libvlc.getPosition() * 100)); 
        vlcDuration.setText(duration); 
       } 
       handlerSeekbar.postDelayed(runnableSeekbar, 1000); 
      } 
     }; 

     runnableSeekbar.run(); 
     vlcSeekbar.setOnSeekBarChangeListener(
       new SeekBar.OnSeekBarChangeListener() 
       { 
        @Override 
        public void onProgressChanged(SeekBar seekBar, int i, boolean b) 
        { 
         Log.v("NEW POS", "pos is : " + i); 
         //if (i != 0) 
         // libvlc.setPosition(((float) i/100.0f)); 
        } 

        @Override 
        public void onStartTrackingTouch(SeekBar seekBar) 
        { 

        } 

        @Override 
        public void onStopTrackingTouch(SeekBar seekBar) 
        { 

        } 
       } 
     ); 

     // OVERLAY 
     handlerOverlay = new Handler(); 
     runnableOverlay = new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       vlcOverlay.setVisibility(View.GONE); 
       toggleFullscreen(true); 
      } 
     }; 
     final long timeToDisappear = 3000; 
     handlerOverlay.postDelayed(runnableOverlay, timeToDisappear); 
     vlcContainer.setOnClickListener(
       new View.OnClickListener() 
       { 
        @Override 
        public void onClick(View view) 
        { 
         vlcOverlay.setVisibility(View.VISIBLE); 

         handlerOverlay.removeCallbacks(runnableOverlay); 
         handlerOverlay.postDelayed(runnableOverlay, timeToDisappear); 
        } 
       } 
     ); 
    } 

    public void playMovie() 
    { 
     if (libvlc != null && libvlc.isPlaying()) 
     { 
      return; 
     } 
     vlcContainer.setVisibility(View.VISIBLE); 
     holder = mSurface.getHolder(); 
     holder.addCallback(this); 
     createPlayer(urlToStream); 
    } 

    private void toggleFullscreen(boolean fullscreen) 
    { 
     WindowManager.LayoutParams attrs = getWindow().getAttributes(); 
     if (fullscreen) 
     { 
      attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN; 
      vlcContainer.setSystemUiVisibility(
        View.SYSTEM_UI_FLAG_LAYOUT_STABLE 
          | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 
          | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 
          | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 
          | View.SYSTEM_UI_FLAG_FULLSCREEN 
          | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 
      ); 
     } 
     else 
     { 
      attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN; 
     } 
     getWindow().setAttributes(attrs); 
    } 

    @Override 
    public void onConfigurationChanged(Configuration newConfig) 
    { 
     super.onConfigurationChanged(newConfig); 
     setSize(mVideoWidth, mVideoHeight); 
    } 

    @Override 
    protected void onResume() 
    { 
     super.onResume(); 
    } 

    @Override 
    protected void onPause() 
    { 
     super.onPause(); 
     //releasePlayer(); 
    } 

    @Override 
    protected void onDestroy() 
    { 
     super.onDestroy(); 
     releasePlayer(); 
    } 

    /** 
    * ********** 
    * Surface 
    * *********** 
    */ 

    public void surfaceCreated(SurfaceHolder holder) 
    { 
    } 

    public void surfaceChanged(SurfaceHolder surfaceholder, int format, 
           int width, int height) 
    { 
     if (libvlc != null) 
     { 
      libvlc.attachSurface(surfaceholder.getSurface(), this); 
     } 
    } 

    public void surfaceDestroyed(SurfaceHolder surfaceholder) 
    { 
    } 

    private void setSize(int width, int height) 
    { 
     mVideoWidth = width; 
     mVideoHeight = height; 
     if (mVideoWidth * mVideoHeight <= 1) 
     { 
      return; 
     } 

     // get screen size 
     int w = getWindow().getDecorView().getWidth(); 
     int h = getWindow().getDecorView().getHeight(); 

     // getWindow().getDecorView() doesn't always take orientation into 
     // account, we have to correct the values 
     boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; 
     if (w > h && isPortrait || w < h && !isPortrait) 
     { 
      int i = w; 
      w = h; 
      h = i; 
     } 

     float videoAR = (float) mVideoWidth/(float) mVideoHeight; 
     float screenAR = (float) w/(float) h; 

     if (screenAR < videoAR) 
     { 
      h = (int) (w/videoAR); 
     } 
     else 
     { 
      w = (int) (h * videoAR); 
     } 

     // force surface buffer size 
     if (holder != null) 
     { 
      holder.setFixedSize(mVideoWidth, mVideoHeight); 
     } 

     // set display size 
     ViewGroup.LayoutParams lp = mSurface.getLayoutParams(); 
     lp.width = w; 
     lp.height = h; 
     mSurface.setLayoutParams(lp); 
     mSurface.invalidate(); 
    } 

    @Override 
    public void setSurfaceSize(int width, int height, int visible_width, 
           int visible_height, int sar_num, int sar_den) 
    { 
     Message msg = Message.obtain(mHandler, VideoSizeChanged, width, height); 
     msg.sendToTarget(); 
    } 

    /** 
    * ********** 
    * Player 
    * *********** 
    */ 

    private void createPlayer(String media) 
    { 
     releasePlayer(); 
     setupControls(); 
     try 
     { 
      if (media.length() > 0) 
      { 
       Toast toast = Toast.makeText(this, media, Toast.LENGTH_LONG); 
       toast.setGravity(
         Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 
         0 
       ); 
       toast.show(); 
      } 

      // Create a new media player 
      libvlc = LibVLC.getInstance(); 
      libvlc.setHardwareAcceleration(LibVLC.HW_ACCELERATION_FULL); 
      libvlc.eventVideoPlayerActivityCreated(true); 
      libvlc.setSubtitlesEncoding(""); 
      libvlc.setAout(LibVLC.AOUT_OPENSLES); 
      libvlc.setTimeStretching(true); 
      libvlc.setChroma("RV32"); 
      libvlc.setVerboseMode(true); 
      LibVLC.restart(this); 
      EventHandler.getInstance().addHandler(mHandler); 
      holder.setFormat(PixelFormat.RGBX_8888); 
      holder.setKeepScreenOn(true); 

      mSubtitlesSurfaceHolder = mSubtitlesSurface.getHolder(); 
      mSubtitlesSurfaceHolder.setFormat(PixelFormat.RGBA_8888); 
      mSubtitlesSurface.setZOrderMediaOverlay(true); 
      //mSubtitlesSurface.setZOrderOnTop(true); 
      mSubtitlesSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT); 
      mSubtitlesSurfaceHolder.addCallback(mSubtitlesSurfaceCallback); 


      MediaList list = libvlc.getMediaList(); 
      list.clear(); 
      list.add(new Media(libvlc, LibVLC.PathToURI(media)), false); 


      libvlc.setVolume(100); 
      libvlc.playIndex(0); 
     } 
     catch (Exception e) 
     { 
      Toast.makeText(this, "Could not create Vlc Player", Toast.LENGTH_LONG).show(); 
     } 
    } 

    private void releasePlayer() 
    { 
     if (handlerSeekbar != null && runnableSeekbar != null) 
     { 
      handlerSeekbar.removeCallbacks(runnableSeekbar); 
     } 
     EventHandler.getInstance().removeHandler(mHandler); 
     if (libvlc == null) 
     { 
      return; 
     } 
     libvlc.stop(); 
     libvlc.detachSurface(); 
     holder = null; 
     libvlc.closeAout(); 

     mVideoWidth = 0; 
     mVideoHeight = 0; 
    } 

    /** 
    * ********** 
    * Events 
    * *********** 
    */ 

    private Handler mHandler = new MyHandler(this); 

    private static class MyHandler extends Handler 
    { 
     private WeakReference<FullscreenVlcPlayer> mOwner; 

     public MyHandler(FullscreenVlcPlayer owner) 
     { 
      mOwner = new WeakReference<FullscreenVlcPlayer>(owner); 
     } 

     @Override 
     public void handleMessage(Message msg) 
     { 
      FullscreenVlcPlayer player = mOwner.get(); 

      // Player events 
      if (msg.what == VideoSizeChanged) 
      { 
       player.setSize(msg.arg1, msg.arg2); 
       return; 
      } 

      // Libvlc events 
      Bundle b = msg.getData(); 
      switch (b.getInt("event")) 
      { 
       case EventHandler.MediaPlayerEndReached: 
        player.releasePlayer(); 
        break; 
       case EventHandler.MediaPlayerPlaying: 
        player.setSubtitles(); 
        break; 
       case EventHandler.MediaPlayerPaused: 
       case EventHandler.MediaPlayerStopped: 
       default: 
        break; 
      } 
     } 
    } 

} 

回答

0

這不是針對Android,但我認爲可以幫助你

/* Create a new item */ 
media = libvlc_media_new_path (inst, "BlackBerry.3gp"); 

/* Create a media player playing environement */ 
mediaplayer = libvlc_media_player_new_from_media (media); 

/* play the media_player */ 
libvlc_media_player_play (mediaplayer); 

//***************************************************************************** 
//***************************************************************************** 
//********* Subtitle section. Must be after libvlc_media_player_play ********** 
//***************************************************************************** 
//***************************************************************************** 
int temp = libvlc_video_set_subtitle_file(mediaplayer, "NewSubFile.srt"); 
printf("sub status=%d\n", temp); 

temp = libvlc_video_set_subtitle_file(mediaplayer, "BlackBerry.srt"); 
printf("sub status=%d\n", temp); 

int sub_count = libvlc_video_get_spu_count(mediaplayer); 
printf("sub count=%d\n", sub_count); 

//***************************************************************************** 
//***************************************************************************** 
//***************************************************************************** 
//***************************************************************************** 
//***************************************************************************** 

sleep (10); /* Let it play a bit */ 

/* No need to keep the media now */ 
libvlc_media_release (media); 
/* Stop playing */ 
libvlc_media_player_stop (mediaplayer); 

/* Free the media_player */ 
libvlc_media_player_release (mediaplayer);