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


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

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

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

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

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

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

关于直播的相关信息这里不做详解,我们对直播应该很熟悉,实现生活中有各种直播,他们如何实现的呢,其实开发一个简单不能简单的直播,只需要两个:1、直播地址 2、播放器,对于直播地址我们可以利用很多软件获取连接,播放器,现在开源的也有很多,最常见的就是ffmpeg,但是如果直接用ffmpeg开发工作量比较大,我们可以使用第三方的播放器库,例如vlc,vitamio等等,这里我使用的时vitamio库。

首先建立一个项目,命名为Live,项目建立好了以后我们需要配置vitamio需要的环境,网上有很多,这里就不写出了,添加了依赖库后添加一个主界面,这里我只添加了一个EditView和Button,配置如下:

 

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  

  2.     xmlns:tools="http://schemas.android.com/tools"  

  3.     android:layout_width="match_parent"  

  4.     android:layout_height="match_parent"  

  5.     android:paddingBottom="@dimen/activity_vertical_margin"  

  6.     android:paddingLeft="@dimen/activity_horizontal_margin"  

  7.     android:paddingRight="@dimen/activity_horizontal_margin"  

  8.     android:paddingTop="@dimen/activity_vertical_margin"  

  9.     tools:context=".Live" >  

  10.   

  11.     <EditText  

  12.         android:id="@+id/live_url"  

  13.         android:layout_width="match_parent"  

  14.         android:layout_height="100dp" />  

  15.   

  16.     <Button  

  17.         android:id="@+id/play"  

  18.         android:layout_width="120dp"  

  19.         android:layout_height="60dp"  

  20.         android:layout_below="@id/live_url"  

  21.         android:layout_centerHorizontal="true"  

  22.         android:layout_marginTop="100dp"  

  23.         android:text="Play" >  

  24.     </Button>  

  25.   

  26. </RelativeLayout>  

主界面的类:

  1. package com.jwzhangjie.live;  

  2.   

  3. import android.os.Bundle;  

  4. import android.app.Activity;  

  5. import android.content.Intent;  

  6. import android.view.Menu;  

  7. import android.view.View;  

  8. import android.view.View.OnClickListener;  

  9. import android.widget.Button;  

  10. import android.widget.EditText;  

  11.   

  12. public class Live extends Activity {  

  13.   

  14.     public static final String  DEFAULTPATH = "http://ipadlive.cntv.soooner.com/cctv_p2p_hdcctv6.m3u8";  

  15.     EditText Live_Url;  

  16.     Button PlayBtn;  

  17.     @Override  

  18.     protected void onCreate(Bundle savedInstanceState) {  

  19.         super.onCreate(savedInstanceState);  

  20.         setContentView(R.layout.activity_live);  

  21.         Live_Url = (EditText)findViewById(R.id.live_url);  

  22.         Live_Url.setText(DEFAULTPATH);  

  23.         PlayBtn = (Button)findViewById(R.id.play);  

  24.         PlayBtn.setOnClickListener(new OnClickListener() {  

  25.             @Override  

  26.             public void onClick(View v) {  

  27.                 Intent intent = new Intent();  

  28.                 intent.setClass(Live.this, JieVideoPlayer.class);  

  29.                 String path = Live_Url.getText().toString();  

  30.                 if (path == null) {  

  31.                     path = DEFAULTPATH;  

  32.                 }  

  33.                 intent.putExtra("path", path);  

  34.                 startActivity(intent);  

  35.             }  

  36.         });  

  37.     }  

  38.   

  39.     @Override  

  40.     public boolean onCreateOptionsMenu(Menu menu) {  

  41.         getMenuInflater().inflate(R.menu.live, menu);  

  42.         return true;  

  43.     }  

  44.   

  45. }  

播放界面的类:

  1. package com.jwzhangjie.live;  

  2.   

  3. import io.vov.vitamio.LibsChecker;  

  4. import io.vov.vitamio.MediaPlayer;  

  5. import io.vov.vitamio.MediaPlayer.OnCompletionListener;  

  6. import io.vov.vitamio.MediaPlayer.OnInfoListener;  

  7. import io.vov.vitamio.widget.MediaController;  

  8. import io.vov.vitamio.widget.VideoView;  

  9. import android.annotation.SuppressLint;  

  10. import android.app.Activity;  

  11. import android.content.Context;  

  12. import android.content.pm.ActivityInfo;  

  13. import android.content.res.Configuration;  

  14. import android.media.AudioManager;  

  15. import android.net.Uri;  

  16. import android.os.Bundle;  

  17. import android.os.Handler;  

  18. import android.os.Message;  

  19. import android.util.Log;  

  20. import android.view.Display;  

  21. import android.view.GestureDetector.SimpleOnGestureListener;  

  22. import android.view.GestureDetector;  

  23. import android.view.MotionEvent;  

  24. import android.view.View;  

  25. import android.view.ViewGroup;  

  26. import android.view.WindowManager;  

  27. import android.widget.ImageView;  

  28.   

  29. @SuppressLint("HandlerLeak")  

  30. public class JieVideoPlayer extends Activity implements OnCompletionListener, OnInfoListener {  

  31.   

  32.     private String mPath;  

  33.     private String mTitle;  

  34.     private VideoView mVideoView;  

  35.     private View mVolumeBrightnessLayout;  

  36.     private ImageView mOperationBg;  

  37.     private ImageView mOperationPercent;  

  38.     private AudioManager mAudioManager;  

  39.     /** 声音 */  

  40.     private int mMaxVolume;  

  41.     /** 当前声音 */  

  42.     private int mVolume = –1;  

  43.     /** 当前亮度 */  

  44.     private float mBrightness = -1f;  

  45.     /** 当前缩放模式 */  

  46.     private int mLayout = VideoView.VIDEO_LAYOUT_ZOOM;  

  47.     private GestureDetector mGestureDetector;  

  48.     private MediaController mMediaController;  

  49.     private View mLoadingView;  

  50.     @Override  

  51.     public void onCreate(Bundle savedInstanceState) {  

  52.         super.onCreate(savedInstanceState);  

  53.   

  54.         if (!LibsChecker.checkVitamioLibs(this))  

  55.             return;  

  56.   

  57.         // ~~~ 获取播放地址和标  

  58.         // ~~~ 绑定控件  

  59.         setContentView(R.layout.videoview);  

  60.         mPath = getIntent().getStringExtra("path");  

  61.         mVideoView = (VideoView) findViewById(R.id.surface_view);  

  62.         mVolumeBrightnessLayout = findViewById(R.id.operation_volume_brightness);  

  63.         mOperationBg = (ImageView) findViewById(R.id.operation_bg);  

  64.         mOperationPercent = (ImageView) findViewById(R.id.operation_percent);  

  65.         mLoadingView = findViewById(R.id.video_loading);  

  66.         // ~~~ 绑定事件  

  67.         mVideoView.setOnCompletionListener(this);  

  68.         mVideoView.setOnInfoListener(this);  

  69.   

  70.         // ~~~ 绑定数据  

  71.         mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);  

  72.         mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);  

  73.           

  74.         if (mPath.startsWith("http:")){  

  75.             mVideoView.setVideoURI(Uri.parse(mPath));  

  76.         }  

  77.         else{  

  78.             mVideoView.setVideoPath(mPath);  

  79.         }  

  80.         //设置显示名称  

  81.         mMediaController = new MediaController(this);  

  82.         mMediaController.setFileName(mTitle);  

  83.         mVideoView.setMediaController(mMediaController);  

  84.         mVideoView.requestFocus();  

  85.   

  86.         mGestureDetector = new GestureDetector(thisnew MyGestureListener());  

  87.         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);  

  88.     }  

  89.   

  90.     @Override  

  91.     protected void onPause() {  

  92.         super.onPause();  

  93.         if (mVideoView != null)  

  94.             mVideoView.pause();  

  95.     }  

  96.   

  97.     @Override  

  98.     protected void onResume() {  

  99.         super.onResume();  

  100.         if (mVideoView != null)  

  101.             mVideoView.resume();  

  102.     }  

  103.   

  104.     @Override  

  105.     protected void onDestroy() {  

  106.         super.onDestroy();  

  107.         if (mVideoView != null)  

  108.             mVideoView.stopPlayback();  

  109.     }  

  110.   

  111.     @Override  

  112.     public boolean onTouchEvent(MotionEvent event) {  

  113.         if (mGestureDetector.onTouchEvent(event))  

  114.             return true;  

  115.   

  116.         // 处理手势结束  

  117.         switch (event.getAction() & MotionEvent.ACTION_MASK) {  

  118.         case MotionEvent.ACTION_UP:  

  119.             endGesture();  

  120.             break;  

  121.         }  

  122.   

  123.         return super.onTouchEvent(event);  

  124.     }  

  125.   

  126.     /** 手势结束 */  

  127.     private void endGesture() {  

  128.         mVolume = –1;  

  129.         mBrightness = -1f;  

  130.   

  131.         // 隐藏  

  132.         mDismissHandler.removeMessages(0);  

  133.         mDismissHandler.sendEmptyMessageDelayed(0500);  

  134.     }  

  135.   

  136.     private class MyGestureListener extends SimpleOnGestureListener {  

  137.   

  138.         /** 双击 */  

  139.         @Override  

  140.         public boolean onDoubleTap(MotionEvent e) {  

  141.             if (mLayout == VideoView.VIDEO_LAYOUT_ZOOM)  

  142.                 mLayout = VideoView.VIDEO_LAYOUT_ORIGIN;  

  143.             else  

  144.                 mLayout++;  

  145.             if (mVideoView != null)  

  146.                 mVideoView.setVideoLayout(mLayout, 0);  

  147.             return true;  

  148.         }  

  149.   

  150.         /** 滑动 */  

  151.         @SuppressWarnings("deprecation")  

  152.         @Override  

  153.         public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {  

  154.             float mOldX = e1.getX(), mOldY = e1.getY();  

  155.             int y = (int) e2.getRawY();  

  156.             Display disp = getWindowManager().getDefaultDisplay();  

  157.             int windowWidth = disp.getWidth();  

  158.             int windowHeight = disp.getHeight();  

  159.   

  160.             if (mOldX > windowWidth * 4.0 / 5)// 右边滑动  

  161.                 onVolumeSlide((mOldY – y) / windowHeight);  

  162.             else if (mOldX < windowWidth / 5.0)// 左边滑动  

  163.                 onBrightnessSlide((mOldY – y) / windowHeight);  

  164.   

  165.             return super.onScroll(e1, e2, distanceX, distanceY);  

  166.         }  

  167.     }  

  168.   

  169.     /** 定时隐藏 */  

  170.     private Handler mDismissHandler = new Handler() {  

  171.         @Override  

  172.         public void handleMessage(Message msg) {  

  173.             mVolumeBrightnessLayout.setVisibility(View.GONE);  

  174.         }  

  175.     };  

  176.   

  177.     /** 

  178.      * 滑动改变声音大小 

  179.      *  

  180.      * @param percent 

  181.      */  

  182.     private void onVolumeSlide(float percent) {  

  183.         if (mVolume == –1) {  

  184.             mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);  

  185.             if (mVolume < 0)  

  186.                 mVolume = 0;  

  187.   

  188.             // 显示  

  189.             mOperationBg.setImageResource(R.drawable.video_volumn_bg);  

  190.             mVolumeBrightnessLayout.setVisibility(View.VISIBLE);  

  191.         }  

  192.   

  193.         int index = (int) (percent * mMaxVolume) + mVolume;  

  194.         if (index > mMaxVolume)  

  195.             index = mMaxVolume;  

  196.         else if (index < 0)  

  197.             index = 0;  

  198.   

  199.         // 变更声音  

  200.         mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);  

  201.   

  202.         // 变更进度�?  

  203.         ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();  

  204.         lp.width = findViewById(R.id.operation_full).getLayoutParams().width * index / mMaxVolume;  

  205.         mOperationPercent.setLayoutParams(lp);  

  206.     }  

  207.   

  208.     /** 

  209.      * 滑动改变亮度 

  210.      *  

  211.      * @param percent 

  212.      */  

  213.     private void onBrightnessSlide(float percent) {  

  214.         if (mBrightness < 0) {  

  215.             mBrightness = getWindow().getAttributes().screenBrightness;  

  216.             if (mBrightness <= 0.00f)  

  217.                 mBrightness = 0.50f;  

  218.             if (mBrightness < 0.01f)  

  219.                 mBrightness = 0.01f;  

  220.   

  221.             // 显示  

  222.             mOperationBg.setImageResource(R.drawable.video_brightness_bg);  

  223.             mVolumeBrightnessLayout.setVisibility(View.VISIBLE);  

  224.         }  

  225.         WindowManager.LayoutParams lpa = getWindow().getAttributes();  

  226.         lpa.screenBrightness = mBrightness + percent;  

  227.         if (lpa.screenBrightness > 1.0f)  

  228.             lpa.screenBrightness = 1.0f;  

  229.         else if (lpa.screenBrightness < 0.01f)  

  230.             lpa.screenBrightness = 0.01f;  

  231.         getWindow().setAttributes(lpa);  

  232.   

  233.         ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();  

  234.         lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness);  

  235.         mOperationPercent.setLayoutParams(lp);  

  236.     }  

  237.   

  238.     @Override  

  239.     public void onConfigurationChanged(Configuration newConfig) {  

  240.         if (mVideoView != null)  

  241.             mVideoView.setVideoLayout(mLayout, 0);  

  242.         super.onConfigurationChanged(newConfig);  

  243.     }  

  244.   

  245.     @Override  

  246.     public void onCompletion(MediaPlayer player) {  

  247.         Log.e("tet""播放完成");  

  248.     }  

  249.   

  250.     private void stopPlayer() {  

  251.         if (mVideoView != null)  

  252.             mVideoView.pause();  

  253.     }  

  254.   

  255.     private void startPlayer() {  

  256.         if (mVideoView != null)  

  257.             mVideoView.start();  

  258.     }  

  259.   

  260.     private boolean isPlaying() {  

  261.         return mVideoView != null && mVideoView.isPlaying();  

  262.     }  

  263.   

  264.     /** 是否�?��自动恢复播放,用于自动暂停,恢复播放 */  

  265.     private boolean needResume;  

  266.   

  267.     @Override  

  268.     public boolean onInfo(MediaPlayer arg0, int arg1, int down_rate) {  

  269.         switch (arg1) {  

  270.         case MediaPlayer.MEDIA_INFO_BUFFERING_START:  

  271.             //�?��缓存,暂停播�?  

  272.             if (isPlaying()) {  

  273.                 stopPlayer();  

  274.                 needResume = true;  

  275.             }  

  276.             mLoadingView.setVisibility(View.VISIBLE);  

  277.             break;  

  278.         case MediaPlayer.MEDIA_INFO_BUFFERING_END:  

  279.             //缓存完成,继续播�?  

  280.             if (needResume)  

  281.                 startPlayer();  

  282.             mLoadingView.setVisibility(View.GONE);  

  283.             break;  

  284.         case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED:  

  285.             //显示 下载速度  

  286.             Log.e("test","download rate:" + down_rate);  

  287. //          mLoadingPerce.setText("正在缓冲�?.."+"缓冲完成�?+down_rate);  

  288.             //mListener.onDownloadRateChanged(arg2);  

  289.             break;  

  290.         }  

  291.         return true;  

  292.     }  

  293. }  

播放界面的配置:

[html] view plain copy print?

  1. <?xml version="1.0" encoding="utf-8"?>  

  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  

  3.     android:layout_width="fill_parent"  

  4.     android:layout_height="fill_parent"  

  5.     android:orientation="vertical" >  

  6.   

  7.     <io.vov.vitamio.widget.VideoView  

  8.         android:id="@+id/surface_view"  

  9.         android:layout_width="fill_parent"  

  10.         android:layout_height="fill_parent"  

  11.         android:layout_centerHorizontal="true"  

  12.         android:layout_centerVertical="true" />  

  13.   

  14.     <LinearLayout  

  15.         android:id="@+id/video_loading"  

  16.         android:layout_width="wrap_content"  

  17.         android:layout_height="wrap_content"  

  18.         android:layout_centerInParent="true"  

  19.         android:gravity="center_vertical" >  

  20.   

  21.         <ProgressBar  

  22.             android:layout_width="wrap_content"  

  23.             android:layout_height="wrap_content" />  

  24.   

  25.         <TextView  

  26.             android:id="@+id/video_loading_perce"  

  27.             android:layout_width="wrap_content"  

  28.             android:layout_height="wrap_content"  

  29.             android:paddingTop="7.0dip"  

  30.             android:text="@string/video_layout_loading"  

  31.             android:textColor="@color/white"  

  32.             android:textSize="20.0sp" />  

  33.     </LinearLayout>  

  34.   

  35.     <FrameLayout  

  36.         android:id="@+id/operation_volume_brightness"  

  37.         android:layout_width="wrap_content"  

  38.         android:layout_height="wrap_content"  

  39.         android:layout_centerInParent="true"  

  40.         android:background="#00000000"  

  41.         android:orientation="horizontal"  

  42.         android:padding="0dip"  

  43.         android:visibility="invisible" >  

  44.   

  45.         <ImageView  

  46.             android:id="@+id/operation_bg"  

  47.             android:layout_width="wrap_content"  

  48.             android:layout_height="wrap_content"  

  49.             android:layout_gravity="center"  

  50.             android:src="@drawable/video_volumn_bg" />  

  51.   

  52.         <FrameLayout  

  53.             android:layout_width="wrap_content"  

  54.             android:layout_height="wrap_content"  

  55.             android:layout_gravity="bottom|center_horizontal"  

  56.             android:paddingBottom="25dip" >  

  57.   

  58.             <ImageView  

  59.                 android:id="@+id/operation_full"  

  60.                 android:layout_width="94dip"  

  61.                 android:layout_height="wrap_content"  

  62.                 android:layout_gravity="left"  

  63.                 android:src="@drawable/video_num_bg" />  

  64.   

  65.             <ImageView  

  66.                 android:id="@+id/operation_percent"  

  67.                 android:layout_width="0dip"  

  68.                 android:layout_height="wrap_content"  

  69.                 android:layout_gravity="left"  

  70.                 android:scaleType="matrix"  

  71.                 android:src="@drawable/video_num_front" />  

  72.         </FrameLayout>  

  73.     </FrameLayout>  

  74.   

  75. </RelativeLayout>  



0 条评论

切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册