使用VLC搭建组播服务器,在客户端进行播放

                      最近,在写一个项目需要用到VLC搭建组播流服务器作为视频源,我这里使用了UDP协议。UDP协议主要作用是将网络数据流量压缩成数据报的形式,一个典型的数据报就是一个二进制的传输单位。每一个数据报的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。总体来说:UDP任然不失为一项非常实用和可行的网络传输协议。

             搭建VLC服务器的流程:

             1.打开VLC;

             2.点击右上角"媒体",在下拉列表中选择"流(s)"

                 

             

             3.打开后,点击"添加",选择要播放的视频资源。我这里是《摆渡人》;

                 

             

             4.选择好视频源后,点击"串流"选项;

                 

           

             5.查看视频路径,以及文件类型,然后点击"下一个"

                            

            

               6.勾选"在本地显示",选择"文件"下拉框,选择协议模式,我这里是UDP协议;

                   

               7.点击"添加",选择目标播放路径(这里的路径我研究了好久,其实有两种地址:1.播放客户端的IP地址; 2.IP组播地址,IP组播地址是一个D类IP地址,范围从224.0.0.0~239.255.255.255 其中还有很多是为特殊地质保留的。而224.0.0.0~224.0.0.255的地址最好不要用,因为他们大多数是为了特殊目的保存的)。点击"下一步".

                   

                   

               8.将"激活转码"去掉,点击"下一个"

                   

               9.  点击"",即可进行播放。

                    

              

             这是VLC的本地播放的视频效果:

                    

                      

             客户端代码(使用维他命的播放框架):

              

public class PlayAcyVertical extends Activity implements
		OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener,
		TextureView.SurfaceTextureListener {
	private static final String TAG = PlayAcyVertical.class.getSimpleName();
	private TextureView mTextureView;
	private String path = "udp://@239.255.255.255:1234";
	private Surface surf;
	private boolean mIsVideoSizeKnown = false;
	private boolean mIsVideoReadyToBePlayed = false;
	SurfaceTexture surfaceTexture;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (!LibsChecker.checkVitamioLibs(this))
			return;
		setContentView(R.layout.acy_play_v);
		InitPlayer();
	}

	public void InitPlayer() {
		mTextureView = (TextureView) findViewById(R.id.surface);
		mTextureView.setSurfaceTextureListener(this);
		mTextureView.setFocusable(true);
		mTextureView.setOnFocusChangeListener(new OnFocusChangeListener() {

			@Override
			public void onFocusChange(View v, boolean hasFocus) {
				if (hasFocus == true) {// 如果获得到焦点
					Toast.makeText(getApplicationContext(), "获取到焦点", 0).show();
				} else {
					Toast.makeText(getApplicationContext(), "没有获取到焦点", 0)
							.show();
				}
			}
		});
	}

	private void playVideo() {
		doCleanUp();
		try {
			mMediaPlayer = new MediaPlayer(this, true);
			mMediaPlayer.setDataSource(path);
			if (surf == null) {
				surf = new Surface(surfaceTexture);
			}
			Toast.makeText(getApplicationContext(), "surf=" + surf, 0).show();
			mMediaPlayer.setSurface(surf);
			mMediaPlayer.prepareAsync();
			mMediaPlayer.setTimedTextShown(true);
			mMediaPlayer.setOnBufferingUpdateListener(this);// 设置缓冲监听
			mMediaPlayer.setOnCompletionListener(this);// 设置播放完毕监听
			mMediaPlayer.setOnPreparedListener(this);// 设置准备完毕监听
			mMediaPlayer.setBufferSize(512 * 1024);
			mMediaPlayer.setVideoQuality(MediaPlayer.VIDEOQUALITY_MEDIUM);
			setVolumeControlStream(AudioManager.STREAM_MUSIC);
			mMediaPlayer.start();
		} catch (Exception e) {
			Toast.makeText(getApplicationContext(), e.getMessage(), 0).show();
		}
	}

	private void doCleanUp() {
		mIsVideoReadyToBePlayed = false;
		mIsVideoSizeKnown = false;
	}

	@Override
	public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
			int height) {
		surfaceTexture = surface;
		playVideo();

	}

	@Override
	public boolean onSurfaceTextureDestroyed(SurfaceTexture arg0) {

		return false;
	}

	@Override
	public void onSurfaceTextureSizeChanged(SurfaceTexture arg0, int arg1,
			int arg2) {

	}

	@Override
	public void onSurfaceTextureUpdated(SurfaceTexture arg0) {

	}

	@Override
	public void onPrepared(MediaPlayer mp) {
		mIsVideoReadyToBePlayed = true;
		if (mIsVideoReadyToBePlayed) {
			startVideoPlayback();
		}
	}

	@Override
	public void onCompletion(MediaPlayer mp) {

	}

	@Override
	public void onBufferingUpdate(MediaPlayer mp, int percent) {

	}

	private void startVideoPlayback() {
		Log.v(TAG, "startVideoPlayback");
		adjustAspectRatio(mMediaPlayer.getVideoWidth(),
				mMediaPlayer.getVideoHeight());
		mMediaPlayer.start();
	}

	public void adjustAspectRatio(int videoWidth, int videoHeight) {
		int viewWidth = mTextureView.getWidth();
		int viewHeight = mTextureView.getHeight();
		double aspectRatio = (double) videoHeight / videoWidth;

		int newWidth, newHeight;
		if (viewHeight > (int) (viewWidth * aspectRatio)) {
			// limited by narrow width; restrict height
			newWidth = viewWidth;
			newHeight = (int) (viewWidth * aspectRatio);
		} else {
			// limited by short height; restrict width
			newWidth = (int) (viewHeight / aspectRatio);
			newHeight = viewHeight;
		}
		int xoff = (viewWidth - newWidth) / 2;
		int yoff = (viewHeight - newHeight) / 2;

		Matrix txform = new Matrix();
		mTextureView.getTransform(txform);
		txform.setScale((float) newWidth / viewWidth, (float) newHeight
				/ viewHeight);
		// txform.postRotate(10); // just for fun
		txform.postTranslate(xoff, yoff);
		mTextureView.setTransform(txform);
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		releaseMediaPlayer();
		doCleanUp();
	}

	private void releaseMediaPlayer() {
		if (mMediaPlayer != null) {
			mMediaPlayer.release();
			mMediaPlayer = null;
		}
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		releaseMediaPlayer();
		doCleanUp();
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}

		return super.onOptionsItemSelected(item);
	}

}

       

            acy_paly_v.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/rel_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextureView
        android:id="@+id/surface"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true" />

</RelativeLayout>

          这就是VLC搭建组播流的基本播放流程。主要代码已经提供了,有什么问题欢迎大家一起交流。






阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭