您的位置:首页 > 移动开发 > Android开发

Android流媒体开发之-直播实现

2016-12-23 19:12 816 查看
1、Android流媒体开发之-直播实现

2、Android流媒体开发之-直播自定义列表

3、Android流媒体开发之-服务器图片的加载

4、Android流媒体开发之-直播自定义分类

5、Android流媒体开发之-获取直播节目预告-1

6、Android流媒体开发之-直播界面切换电视台频道

关于直播的相关信息这里不做详解,我们对直播应该很熟悉,实现生活中有各种直播,他们如何实现的呢,其实开发一个简单不能简单的直播,只需要两个: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"
4000

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>

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: