关于直播的相关信息这里不做详解,我们对直播应该很熟悉,实现生活中有各种直播,他们如何实现的呢,其实开发一个简单不能简单的直播,只需要两个: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;
-
@Override
-
protected 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() {
-
@Override
-
public 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);
-
}
-
});
-
}
-
-
@Override
-
public 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;
-
@Override
-
public 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);
-
}
-
-
@Override
-
protected void onPause() {
-
super.onPause();
-
if (mVideoView != null)
-
mVideoView.pause();
-
}
-
-
@Override
-
protected void onResume() {
-
super.onResume();
-
if (mVideoView != null)
-
mVideoView.resume();
-
}
-
-
@Override
-
protected void onDestroy() {
-
super.onDestroy();
-
if (mVideoView != null)
-
mVideoView.stopPlayback();
-
}
-
-
@Override
-
public 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 {
-
-
/** 双击 */
-
@Override
-
public boolean onDoubleTap(MotionEvent e) {
-
if (mLayout == VideoView.VIDEO_LAYOUT_ZOOM)
-
mLayout = VideoView.VIDEO_LAYOUT_ORIGIN;
-
else
-
mLayout++;
-
if (mVideoView != null)
-
mVideoView.setVideoLayout(mLayout, 0);
-
return true;
-
}
-
-
/** 滑动 */
-
@SuppressWarnings("deprecation")
-
@Override
-
public 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() {
-
@Override
-
public 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);
-
}
-
-
@Override
-
public void onConfigurationChanged(Configuration newConfig) {
-
if (mVideoView != null)
-
mVideoView.setVideoLayout(mLayout, 0);
-
super.onConfigurationChanged(newConfig);
-
}
-
-
@Override
-
public 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;
-
-
@Override
-
public 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;
-
}
-
}
播放界面的配置:
[html] view plain copy print?
-
<?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>