流媒體開發之–直播實現

來源:互聯網
上載者:User

關於直播的相關資訊這裡不做詳解,我們對直播應該很熟悉,實現生活中有各種直播,他們如何?的呢,其實開發一個簡單不能簡單的直播,只需要兩個:1、直播地址 2、播放器,對於直播地址我們可以利用很多軟體擷取串連,播放器,現在開源的也有很多,最常見的就是ffmpeg,但是如果直接用ffmpeg開發工作量比較大,我們可以使用第三方的播放器庫,例如vlc,vitamio等等,這裡我使用的時vitamio庫。

首先建立一個項目,命名為Live,項目建立好了以後我們需要配置vitamio需要的環境,網上有很多,這裡就不寫出了,添加了依賴庫後添加一個主介面,這裡我只添加了一個EditView和Button,配置如下:

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".Live" >    <EditText        android:id="@+id/live_url"        android:layout_width="match_parent"        android:layout_height="100dp" />    <Button        android:id="@+id/play"        android:layout_width="120dp"        android:layout_height="60dp"        android:layout_below="@id/live_url"        android:layout_centerHorizontal="true"        android:layout_marginTop="100dp"        android:text="Play" >    </Button></RelativeLayout>

主介面的類:

package com.jwzhangjie.live;import android.os.Bundle;import android.app.Activity;import android.content.Intent;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;public class Live extends Activity {public static final String  DEFAULTPATH = "http://ipadlive.cntv.soooner.com/cctv_p2p_hdcctv6.m3u8";EditText Live_Url;Button PlayBtn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_live);Live_Url = (EditText)findViewById(R.id.live_url);Live_Url.setText(DEFAULTPATH);PlayBtn = (Button)findViewById(R.id.play);PlayBtn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.setClass(Live.this, JieVideoPlayer.class);String path = Live_Url.getText().toString();if (path == null) {path = DEFAULTPATH;}intent.putExtra("path", path);startActivity(intent);}});}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.live, menu);return true;}}

播放介面的類:

package com.jwzhangjie.live;import io.vov.vitamio.LibsChecker;import io.vov.vitamio.MediaPlayer;import io.vov.vitamio.MediaPlayer.OnCompletionListener;import io.vov.vitamio.MediaPlayer.OnInfoListener;import io.vov.vitamio.widget.MediaController;import io.vov.vitamio.widget.VideoView;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Context;import android.content.pm.ActivityInfo;import android.content.res.Configuration;import android.media.AudioManager;import android.net.Uri;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.Display;import android.view.GestureDetector.SimpleOnGestureListener;import android.view.GestureDetector;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.ImageView;@SuppressLint("HandlerLeak")public class JieVideoPlayer extends Activity implements OnCompletionListener, OnInfoListener {private String mPath;private String mTitle;private VideoView mVideoView;private View mVolumeBrightnessLayout;private ImageView mOperationBg;private ImageView mOperationPercent;private AudioManager mAudioManager;/** 聲音 */private int mMaxVolume;/** 當前聲音 */private int mVolume = -1;/** 當前亮度 */private float mBrightness = -1f;/** 當前縮放模式 */private int mLayout = VideoView.VIDEO_LAYOUT_ZOOM;private GestureDetector mGestureDetector;private MediaController mMediaController;private View mLoadingView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);if (!LibsChecker.checkVitamioLibs(this))return;// ~~~ 擷取播放地址和標// ~~~ 繫結控制項setContentView(R.layout.videoview);mPath = getIntent().getStringExtra("path");mVideoView = (VideoView) findViewById(R.id.surface_view);mVolumeBrightnessLayout = findViewById(R.id.operation_volume_brightness);mOperationBg = (ImageView) findViewById(R.id.operation_bg);mOperationPercent = (ImageView) findViewById(R.id.operation_percent);mLoadingView = findViewById(R.id.video_loading);// ~~~ 綁定事件mVideoView.setOnCompletionListener(this);mVideoView.setOnInfoListener(this);// ~~~ 綁定資料mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);if (mPath.startsWith("http:")){mVideoView.setVideoURI(Uri.parse(mPath));}else{mVideoView.setVideoPath(mPath);}//設定顯示名稱mMediaController = new MediaController(this);mMediaController.setFileName(mTitle);mVideoView.setMediaController(mMediaController);mVideoView.requestFocus();mGestureDetector = new GestureDetector(this, new MyGestureListener());setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);}@Overrideprotected void onPause() {super.onPause();if (mVideoView != null)mVideoView.pause();}@Overrideprotected void onResume() {super.onResume();if (mVideoView != null)mVideoView.resume();}@Overrideprotected void onDestroy() {super.onDestroy();if (mVideoView != null)mVideoView.stopPlayback();}@Overridepublic boolean onTouchEvent(MotionEvent event) {if (mGestureDetector.onTouchEvent(event))return true;// 處理手勢結束switch (event.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_UP:endGesture();break;}return super.onTouchEvent(event);}/** 手勢結束 */private void endGesture() {mVolume = -1;mBrightness = -1f;// 隱藏mDismissHandler.removeMessages(0);mDismissHandler.sendEmptyMessageDelayed(0, 500);}private class MyGestureListener extends SimpleOnGestureListener {/** 雙擊 */@Overridepublic boolean onDoubleTap(MotionEvent e) {if (mLayout == VideoView.VIDEO_LAYOUT_ZOOM)mLayout = VideoView.VIDEO_LAYOUT_ORIGIN;elsemLayout++;if (mVideoView != null)mVideoView.setVideoLayout(mLayout, 0);return true;}/** 滑動 */@SuppressWarnings("deprecation")@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {float mOldX = e1.getX(), mOldY = e1.getY();int y = (int) e2.getRawY();Display disp = getWindowManager().getDefaultDisplay();int windowWidth = disp.getWidth();int windowHeight = disp.getHeight();if (mOldX > windowWidth * 4.0 / 5)// 右邊滑動onVolumeSlide((mOldY - y) / windowHeight);else if (mOldX < windowWidth / 5.0)// 左邊滑動onBrightnessSlide((mOldY - y) / windowHeight);return super.onScroll(e1, e2, distanceX, distanceY);}}/** 定時隱藏 */private Handler mDismissHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {mVolumeBrightnessLayout.setVisibility(View.GONE);}};/** * 滑動改變聲音大小 *  * @param percent */private void onVolumeSlide(float percent) {if (mVolume == -1) {mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);if (mVolume < 0)mVolume = 0;// 顯示mOperationBg.setImageResource(R.drawable.video_volumn_bg);mVolumeBrightnessLayout.setVisibility(View.VISIBLE);}int index = (int) (percent * mMaxVolume) + mVolume;if (index > mMaxVolume)index = mMaxVolume;else if (index < 0)index = 0;// 變更聲音mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);// 變更進度�?ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();lp.width = findViewById(R.id.operation_full).getLayoutParams().width * index / mMaxVolume;mOperationPercent.setLayoutParams(lp);}/** * 滑動改變亮度 *  * @param percent */private void onBrightnessSlide(float percent) {if (mBrightness < 0) {mBrightness = getWindow().getAttributes().screenBrightness;if (mBrightness <= 0.00f)mBrightness = 0.50f;if (mBrightness < 0.01f)mBrightness = 0.01f;// 顯示mOperationBg.setImageResource(R.drawable.video_brightness_bg);mVolumeBrightnessLayout.setVisibility(View.VISIBLE);}WindowManager.LayoutParams lpa = getWindow().getAttributes();lpa.screenBrightness = mBrightness + percent;if (lpa.screenBrightness > 1.0f)lpa.screenBrightness = 1.0f;else if (lpa.screenBrightness < 0.01f)lpa.screenBrightness = 0.01f;getWindow().setAttributes(lpa);ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness);mOperationPercent.setLayoutParams(lp);}@Overridepublic void onConfigurationChanged(Configuration newConfig) {if (mVideoView != null)mVideoView.setVideoLayout(mLayout, 0);super.onConfigurationChanged(newConfig);}@Overridepublic void onCompletion(MediaPlayer player) {Log.e("tet", "播放完成");}private void stopPlayer() {if (mVideoView != null)mVideoView.pause();}private void startPlayer() {if (mVideoView != null)mVideoView.start();}private boolean isPlaying() {return mVideoView != null && mVideoView.isPlaying();}/** 是否�?��自動回復播放,用於自動暫停,恢複播放 */private boolean needResume;@Overridepublic boolean onInfo(MediaPlayer arg0, int arg1, int down_rate) {switch (arg1) {case MediaPlayer.MEDIA_INFO_BUFFERING_START://�?��緩衝,暫停播�?if (isPlaying()) {stopPlayer();needResume = true;}mLoadingView.setVisibility(View.VISIBLE);break;case MediaPlayer.MEDIA_INFO_BUFFERING_END://緩衝完成,繼續播�?if (needResume)startPlayer();mLoadingView.setVisibility(View.GONE);break;case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED://顯示 下載速度Log.e("test","download rate:" + down_rate);//mLoadingPerce.setText("正在緩衝�?.."+"緩衝完成�?+down_rate);//mListener.onDownloadRateChanged(arg2);break;}return true;}}

播放介面的配置:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <io.vov.vitamio.widget.VideoView        android:id="@+id/surface_view"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:layout_centerHorizontal="true"        android:layout_centerVertical="true" />    <LinearLayout        android:id="@+id/video_loading"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:gravity="center_vertical" >        <ProgressBar            android:layout_width="wrap_content"            android:layout_height="wrap_content" />        <TextView            android:id="@+id/video_loading_perce"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:paddingTop="7.0dip"            android:text="@string/video_layout_loading"            android:textColor="@color/white"            android:textSize="20.0sp" />    </LinearLayout>    <FrameLayout        android:id="@+id/operation_volume_brightness"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:background="#00000000"        android:orientation="horizontal"        android:padding="0dip"        android:visibility="invisible" >        <ImageView            android:id="@+id/operation_bg"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center"            android:src="@drawable/video_volumn_bg" />        <FrameLayout            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="bottom|center_horizontal"            android:paddingBottom="25dip" >            <ImageView                android:id="@+id/operation_full"                android:layout_width="94dip"                android:layout_height="wrap_content"                android:layout_gravity="left"                android:src="@drawable/video_num_bg" />            <ImageView                android:id="@+id/operation_percent"                android:layout_width="0dip"                android:layout_height="wrap_content"                android:layout_gravity="left"                android:scaleType="matrix"                android:src="@drawable/video_num_front" />        </FrameLayout>    </FrameLayout></RelativeLayout>

播放的顯示效果:

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.