概述
Vitamio 是一款 Android 与 iOS 平台上的全能多媒体开发框架,全面支持硬件解码与 GPU 渲染,底层音视频解码原理基于FFmpeg开发。Vitamio 凭借其简洁易用的 API 接口赢得了全球众多开发者的青睐。到目前,全球已经有超过一万款应用在使用 Vitamio,覆盖用户超过 5亿。
Vitamio 能够流畅播放720P甚至1080P高清MKV,FLV,MP4,MOV,TS,RMVB等常见格式的视频,还可以在 Android 上支持 MMS, RTSP, RTMP, HLS(m3u8) 等常见的多种视频流媒体协议,包括点播与直播。
支持 ARMv6 和 ARMv7 两种 ARM CPU,同时对 VFP, VFPv3, NEON 等指令集都做相应优化。
支持 Android 2.1+ 系统,支持超过 95% 的 Android 市场。同时 Android 2.1 之前的系统也基本支持,不过没做详细测试。
开源项目下载地址:https://github.com/yixia/VitamioBundle
配置Vitamio
导包
开源项目下载后目录结构如下:
其中的VitamioListActivity是官方提供的demo,而我们要导入的包是InitActivity。
Eclipse用户很简单,直接添加InitActivity为依赖工程即可。
Studio用户下载Studio Vitamio包,作为Module导入Project,然后修改以下信息:
app目录下的build.gradle,在dependencies 中添加依赖 compile project(‘:vitamio’) 如果你导入module中更改过名字的话 要改成修改后的名字 如图:
按照app目录下的build.gradle配置vitamio目录下的build.gradle(注意不是vitamio文件夹下app下的)
AndroidManifest配置
注册io.vov.vitamio.activity.InitActivity:
<activity android:name="io.vov.vitamio.activity.InitActivity" android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation" android:launchMode="singleTop" android:theme="@android:style/Theme.NoTitleBar" android:windowSoftInputMode="stateAlwaysHidden" />
添加权限:
<uses-permission android:name="android.permission.WAKE_LOCK" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
使用Vitamio
VideoView控件的使用
<?xml version="1.0" encoding="utf-8"?><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:background="#696969" tools:context="com.hx.vitamio.MainActivity" > <io.vov.vitamio.widget.CenterLayout android:id="@+id/dd" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <io.vov.vitamio.widget.VideoView android:id="@+id/vitamio" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerHorizontal="true" android:layout_centerVertical="true" /> io.vov.vitamio.widget.CenterLayout> <TextView android:id="@+id/buffer_percent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/dd" android:layout_marginLeft="12dp" android:textColor="#e6ff01" /> <TextView android:id="@+id/net_speed" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/dd" android:layout_marginLeft="12dp" android:layout_toRightOf="@id/buffer_percent" android:textColor="#04fa00" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:background="@mipmap/mediacontroller_sreen_size_100" android:onClick="changeLayout" />RelativeLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
public class MainActivity extends Activity { private VideoView videoView; private TextView percentTv; private TextView netSpeedTv; private int mVideoLayout = 0; private String url1 = "http://112.253.22.157/17/z/z/y/u/zzyuasjwufnqerzvyxgkuigrkcatxr/hc.yinyuetai.com/D046015255134077DDB3ACA0D7E68D45.flv"; private String url2 = "http://flashmedia.eastday.com/newdate/news/2016-11/shznews1125-19.mp4"; private String url3 = "rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov"; private String url4 = "http://42.96.249.166/live/388.m3u8"; private String url5 = "http://live.3gv.ifeng.com/zixun.m3u8"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!LibsChecker.checkVitamioLibs(this)) { return; } setContentView(R.layout.activity_main); percentTv = (TextView) findViewById(R.id.buffer_percent); netSpeedTv = (TextView) findViewById(R.id.net_speed); if (Vitamio.isInitialized(this)) { videoView = (VideoView) findViewById(R.id.vitamio); videoView.setVideoURI(Uri.parse(url1)); videoView.setVideoQuality(MediaPlayer.VIDEOQUALITY_HIGH); MediaController controller = new MediaController(this); videoView.setMediaController(controller); videoView.setBufferSize(10240); videoView.requestFocus(); videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { mediaPlayer.setPlaybackSpeed(1.0f); } }); videoView.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() { @Override public void onBufferingUpdate(MediaPlayer mp, int percent) { percentTv.setText("已缓冲:" + percent + "%"); } }); videoView.setOnInfoListener(new MediaPlayer.OnInfoListener() { @Override public boolean onInfo(MediaPlayer mp, int what, int extra) { switch (what) { case MediaPlayer.MEDIA_INFO_BUFFERING_START: percentTv.setVisibility(View.VISIBLE); netSpeedTv.setVisibility(View.VISIBLE); mp.pause(); break; case MediaPlayer.MEDIA_INFO_BUFFERING_END: percentTv.setVisibility(View.GONE); netSpeedTv.setVisibility(View.GONE); mp.start(); break; case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED: netSpeedTv.setText("当前网速:" + extra + "kb/s"); break; } return true; } }); } } public void changeLayout(View view) { mVideoLayout++; if (mVideoLayout == 4) { mVideoLayout = 0; } switch (mVideoLayout) { case 0: mVideoLayout = VideoView.VIDEO_LAYOUT_ORIGIN; view.setBackgroundResource(R.mipmap.mediacontroller_sreen_size_100); break; case 1: mVideoLayout = VideoView.VIDEO_LAYOUT_SCALE; view.setBackgroundResource(R.mipmap.mediacontroller_screen_fit); break; case 2: mVideoLayout = VideoView.VIDEO_LAYOUT_STRETCH; view.setBackgroundResource(R.mipmap.mediacontroller_screen_size); break; case 3: mVideoLayout = VideoView.VIDEO_LAYOUT_ZOOM; view.setBackgroundResource(R.mipmap.mediacontroller_sreen_size_crop); break; } videoView.setVideoLayout(mVideoLayout, 0); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
注:网速慢的情况下,视频可能会缓冲很久才会播放,这时候可以通过setBufferSize设置视频缓冲大小。默认1024KB,我们可以给它改小点。
VideoView常用函数
/** * 获取扫描视频的Uri。 * 参数layout(缩放参数)参见MediaPlayer的常量:VIDEO_LAYOUT_ORIGIN(原始大小)、VIDEO_LAYOUT_SCALE(画面全屏)、VIDEO_LAYOUT_STRETCH(画面拉伸)、VIDEO_LAYOUT_ZOOM(画面裁剪)、VIDEO_LAYOUT_FIT_PARENT(画面铺满) * 参数aspectRation(宽高比),为0将自动检测 */public void setVideoLayout(int layout,float aspectRatio);public boolean isValid();public void setVideoPath(String path);public void setVideoURI(Uri uri);public void stopPlayback();/** * 设置媒体控制器。 * 参数controller:媒体控制器,注意是io.vov.vitamio.widget.MediaController。 */public void setMediaController(MediaController controller); public void setOnPreparedListener(OnPreparedListener l);public long getCurrentPosition();public void seekTo(long msec);public boolean isPlaying();public int getBufferPercentage();/** * 设置视频质量。 * 参数quality参见MediaPlayer的常量:VIDEOQUALITY_LOW(流畅)、VIDEOQUALITY_MEDIUM(普通)、VIDEOQUALITY_HIGH(高质) */public void setVideoQuality(int quality);public void setBufferSize(int bufSize);public boolean isBuffering();public void setMetaEncoding(String encoding);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
更多方法参见:http://www.cnblogs.com/over140/archive/2012/08/30/2663243.html
Vitamio支持的流
Android RTMP流
Real Time Messaging Protocol (RTMP)是一个Adobe Systems所拥有的一个协议。该协议是Adobe公司拥有的开发音视频流的flash player。后来该协议的部分被公开,供公众使用。这个协议大多用于IPTV和实时视频点播流,但它也用于其他领用。
在android上,标准的VideoView不支持RTMP播放。但WebView可以播放RTMP流。这解决了播放RTMP流的问题,但是我认为web apps 不能提供一个很好的界面和体验。因此这个android RTMP例子中我们将运用第三方库-Vitamio 直播RTMP流的流媒体。
Android RTSP流
实时流协议(RTSP)通过多媒体服务器传输内容,例如YouTube使用RTSP流发布内容。关于RTSP流比较容易的部分是,它可以通过android标准的VideoView来完成。
但是如果你使用Vitamio库,可以更好的播放RTSP流。事实上Vitamio也支持RTSP流的回播。
Android m3u8流
“如何在android上播放m3u8视频”是android开发者最常见的问题之一。通过Http 协议进行视频流直播最简单的办法就是使用标准的 VideoView. 但只能在android3.0以上的设备上播放m3u8流。因为在Android 3.0引入HTTP/ HTTPS直播和HTTP/ HTTPS渐进式流媒体协议,在android3.1完全支持HTTPS。
如果你希望在早期的版本上实现支持android m3u8流的HTTP实时流媒体 (HLS)。应该考虑使用Vitamio库,这个库支持在android API7以上播放m3u8。
Android MMS流
Vitamio库是一个强大的库,还支持Microsoft媒体服务器(MMS)流中的播放。 MMS是网络流媒体协议,主要用于网络广播和电台直播。
注:Vitamio是一个强大的多平台库(ios and android)。通过使用Vitamio库能播放多种类型的视频格式和协议如RTMP, RTSP, HTTP Live, HTTP渐进式流协议。另外一个很好的功能是,vitamio支持字幕和多音轨的播放。Vitamio的唯一的缺点是,它不是完全的开源。您可能需要购买许可证来使用它。
基于Vitamio实现的播放器
下面将Vitamio的视频控制器(MediaController)界面进行自定义,同时支持视频亮度、音量的调节,话不多说,先上效果图。
功能:
- 使用Vitamio的VideoView进行视频播放
- 显示加载进度和当前网速
- 视频左侧界面(左1/4以内)上下滑动调节亮度
- 视频右侧界面(右3/4以外)上下滑动调节声音
- 双击播放/暂停
- 中间播放按钮也可以控制播放/暂停
- 进度显示,并可以拖动调节当前播放进度
(1)播放视频
public class MainActivity extends Activity { private VideoView mVideoView; private TextView downloadRateView, loadRateView; private ProgressBar pb; private CustomMediaController mCustomMediaController; private String url1 = "http://112.253.22.157/17/z/z/y/u/zzyuasjwufnqerzvyxgkuigrkcatxr/hc.yinyuetai.com/D046015255134077DDB3ACA0D7E68D45.flv"; private String url2 = "http://flashmedia.eastday.com/newdate/news/2016-11/shznews1125-19.mp4"; private String url3 = "rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov"; private String url4 = "http://42.96.249.166/live/24035.m3u8"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN; Window window = MainActivity.this.getWindow(); window.setFlags(flag, flag); if (!LibsChecker.checkVitamioLibs(this)) { return; } setContentView(R.layout.activity_main); pb = (ProgressBar) findViewById(R.id.probar); downloadRateView = (TextView) findViewById(R.id.download_rate); loadRateView = (TextView) findViewById(R.id.load_rate); mVideoView = (VideoView) findViewById(R.id.buffer); mCustomMediaController = new CustomMediaController(this,mVideoView,this); mCustomMediaController.setVideoName("蓝莲花"); mCustomMediaController.show(5000); if (Vitamio.isInitialized(this)) { mVideoView.setVideoURI(Uri.parse(url1)); mVideoView.setVideoQuality(MediaPlayer.VIDEOQUALITY_HIGH); mVideoView.setMediaController(mCustomMediaController); mVideoView.setBufferSize(10240); mVideoView.requestFocus(); mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { mediaPlayer.setPlaybackSpeed(1.0f); } }); mVideoView.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() { @Override public void onBufferingUpdate(MediaPlayer mp, int percent) { loadRateView.setText(percent + "%"); } }); mVideoView.setOnInfoListener(new MediaPlayer.OnInfoListener() { @Override public boolean onInfo(MediaPlayer mp, int what, int extra) { switch (what) { case MediaPlayer.MEDIA_INFO_BUFFERING_START: if (mVideoView.isPlaying()) { mVideoView.pause(); pb.setVisibility(View.VISIBLE); downloadRateView.setText(""); loadRateView.setText(""); downloadRateView.setVisibility(View.VISIBLE); loadRateView.setVisibility(View.VISIBLE); } break; case MediaPlayer.MEDIA_INFO_BUFFERING_END: mVideoView.start(); pb.setVisibility(View.GONE); downloadRateView.setVisibility(View.GONE); loadRateView.setVisibility(View.GONE); break; case MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED: downloadRateView.setText("" + extra + "kb/s" + " "); break; } return true; } }); } } @Override public void onConfigurationChanged(Configuration newConfig) { if (mVideoView != null){ mVideoView.setVideoLayout(VideoView.VIDEO_LAYOUT_SCALE, 0); } super.onConfigurationChanged(newConfig); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
(2)视频界面
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <io.vov.vitamio.widget.CenterLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <io.vov.vitamio.widget.VideoView android:id="@+id/buffer" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerHorizontal="true" android:layout_centerVertical="true" /> io.vov.vitamio.widget.CenterLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:orientation="horizontal"> <ProgressBar android:id="@+id/probar" style="?android:attr/progressBarStyleLarge" android:layout_width="50dp" android:layout_height="50dp" /> <TextView android:id="@+id/download_rate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="" android:textColor="#FFFFFF" /> <TextView android:id="@+id/load_rate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="" android:textColor="#FFFFFF" /> LinearLayout>RelativeLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
(3)视频控制器
/** * 自定义视频控制器 */public class CustomMediaController extends MediaController { private static final int HIDEFRAM = 0; private GestureDetector mGestureDetector; private ImageButton img_back; private TextView mFileName; private VideoView videoView; private Activity activity; private Context context; private String videoname; private int controllerWidth = 0; private View mVolumeBrightnessLayout; private ImageView mOperationBg; private TextView mOperationTv; private AudioManager mAudioManager; private int mMaxVolume; private int mVolume = -1; private float mBrightness = -1f; private Handler myHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case HIDEFRAM: mVolumeBrightnessLayout.setVisibility(View.GONE); break; } } }; public CustomMediaController(Context context, VideoView videoView, Activity activity) { super(context); this.context = context; this.videoView = videoView; this.activity = activity; WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); controllerWidth = wm.getDefaultDisplay().getWidth(); mGestureDetector = new GestureDetector(context, new MyGestureListener()); } @Override protected View makeControllerView() { View v = ((LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.mymediacontroller, this); v.setMinimumHeight(controllerWidth); img_back = (ImageButton) v.findViewById(R.id.mediacontroller_top_back); mFileName = (TextView) v.findViewById(R.id.mediacontroller_filename); if (mFileName != null) { mFileName.setText(videoname); } mVolumeBrightnessLayout = (RelativeLayout) v.findViewById(R.id.operation_volume_brightness); mOperationBg = (ImageView) v.findViewById(R.id.operation_bg); mOperationTv = (TextView) v.findViewById(R.id.operation_tv); mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); img_back.setOnClickListener(backListener); return v; } private View.OnClickListener backListener = new View.OnClickListener() { public void onClick(View v) { if (activity != null) { activity.finish(); } } }; @Override public boolean dispatchKeyEvent(KeyEvent event) { System.out.println("MYApp-MyMediaController-dispatchKeyEvent"); return true; } @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; myHandler.removeMessages(HIDEFRAM); myHandler.sendEmptyMessageDelayed(HIDEFRAM, 500); } private class MyGestureListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onSingleTapUp(MotionEvent e) { return false; } /** * 因为使用的是自定义的mediaController 当显示后,mediaController会铺满屏幕, * 所以VideoView的点击事件会被拦截,所以重写控制器的手势事件, * 将全部的操作全部写在控制器中, * 因为点击事件被控制器拦截,无法传递到下层的VideoView, * 所以原来的单击隐藏会失效,作为代替, * 在手势监听中onSingleTapConfirmed()添加自定义的隐藏/显示, * * @param e * @return */ @Override public boolean onSingleTapConfirmed(MotionEvent e) { toggleMediaControlsVisiblity(); return super.onSingleTapConfirmed(e); } @Override public boolean onDown(MotionEvent e) { return true; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { float mOldX = e1.getX(), mOldY = e1.getY(); int y = (int) e2.getRawY(); int x = (int) e2.getRawX(); Display disp = activity.getWindowManager().getDefaultDisplay(); int windowWidth = disp.getWidth(); int windowHeight = disp.getHeight(); if (mOldX > windowWidth * 3.0 / 4.0) { onVolumeSlide((mOldY - y) / windowHeight); } else if (mOldX < windowWidth * 1.0 / 4.0) { onBrightnessSlide((mOldY - y) / windowHeight); } return super.onScroll(e1, e2, distanceX, distanceY); } @Override public boolean onDoubleTap(MotionEvent e) { playOrPause(); return true; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return super.onFling(e1, e2, velocityX, velocityY); } } /** * 滑动改变声音大小 * * @param percent */ private void onVolumeSlide(float percent) { if (mVolume == -1) { mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); if (mVolume < 0) mVolume = 0; 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); mOperationTv.setText((int) (((double) index / mMaxVolume) * 100) + "%"); if (index >= 10) { mOperationBg.setImageResource(R.drawable.volmn_100); } else if (index >= 5 && index < 10) { mOperationBg.setImageResource(R.drawable.volmn_60); } else if (index > 0 && index < 5) { mOperationBg.setImageResource(R.drawable.volmn_30); } else { mOperationBg.setImageResource(R.drawable.volmn_no); } } /** * 滑动改变亮度 * * @param percent */ private void onBrightnessSlide(float percent) { if (mBrightness < 0) { mBrightness = activity.getWindow().getAttributes().screenBrightness; if (mBrightness <= 0.00f) mBrightness = 0.50f; if (mBrightness < 0.01f) mBrightness = 0.01f; mVolumeBrightnessLayout.setVisibility(View.VISIBLE); } WindowManager.LayoutParams lpa = activity.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; } activity.getWindow().setAttributes(lpa); mOperationTv.setText((int) (lpa.screenBrightness * 100) + "%"); if (lpa.screenBrightness * 100 >= 90) { mOperationBg.setImageResource(R.drawable.light_100); } else if (lpa.screenBrightness * 100 >= 80 && lpa.screenBrightness * 100 < 90) { mOperationBg.setImageResource(R.drawable.light_90); } else if (lpa.screenBrightness * 100 >= 70 && lpa.screenBrightness * 100 < 80) { mOperationBg.setImageResource(R.drawable.light_80); } else if (lpa.screenBrightness * 100 >= 60 && lpa.screenBrightness * 100 < 70) { mOperationBg.setImageResource(R.drawable.light_70); } else if (lpa.screenBrightness * 100 >= 50 && lpa.screenBrightness * 100 < 60) { mOperationBg.setImageResource(R.drawable.light_60); } else if (lpa.screenBrightness * 100 >= 40 && lpa.screenBrightness * 100 < 50) { mOperationBg.setImageResource(R.drawable.light_50); } else if (lpa.screenBrightness * 100 >= 30 && lpa.screenBrightness * 100 < 40) { mOperationBg.setImageResource(R.drawable.light_40); } else if (lpa.screenBrightness * 100 >= 20 && lpa.screenBrightness * 100 < 20) { mOperationBg.setImageResource(R.drawable.light_30); } else if (lpa.screenBrightness * 100 >= 10 && lpa.screenBrightness * 100 < 20) { mOperationBg.setImageResource(R.drawable.light_20); } } /** * 设置视频文件名 * * @param name */ public void setVideoName(String name) { videoname = name; if (mFileName != null) { mFileName.setText(name); } } /** * 隐藏或显示 */ private void toggleMediaControlsVisiblity() { if (isShowing()) { hide(); } else { show(); } } /** * 播放/暂停 */ private void playOrPause() { if (videoView != null) if (videoView.isPlaying()) { videoView.pause(); } else { videoView.start(); } }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
(4)视频控制器界面
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:layout_width="match_parent" android:layout_height="34dp" android:background="#77000000"> <ImageButton android:id="@+id/mediacontroller_top_back" android:layout_width="50dp" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:background="@null" android:src="@drawable/ic_player_close_white" /> <TextView android:id="@+id/mediacontroller_filename" style="@style/MediaController_Text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="5dp" android:layout_toRightOf="@+id/mediacontroller_top_back" android:ellipsize="marquee" android:singleLine="true" android:text="file name" /> <ImageButton android:id="@+id/mediacontroller_share" android:layout_width="50dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:background="@null" android:src="@drawable/ic_action_share_without_padding" /> <ImageButton android:id="@+id/mediacontroller_favorite" android:layout_width="50dp" android:layout_height="match_parent" android:layout_toLeftOf="@id/mediacontroller_share" android:background="@null" android:src="@drawable/ic_action_favorites" /> RelativeLayout> <ImageButton android:id="@+id/mediacontroller_play_pause" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="@null" android:src="@drawable/play_selector" /> <RelativeLayout android:id="@+id/operation_volume_brightness" android:layout_width="150dp" android:layout_height="75dp" android:layout_centerInParent="true" android:background="@drawable/videobg" android:orientation="horizontal" android:padding="0dip" android:visibility="gone"> <ImageView android:id="@+id/operation_bg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@drawable/video_volumn_bg" /> <TextView android:id="@+id/operation_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/operation_bg" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:textColor="#ffffff" android:textSize="12sp" /> RelativeLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="50dp" android:layout_alignParentBottom="true" android:background="#77000000"> <TextView android:id="@+id/mediacontroller_time_current" style="@style/MediaController_Text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="15dp" android:text="33:33:33" /> <TextView android:id="@+id/mediacontroller_time_total" style="@style/MediaController_Text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="15dp" android:text="33:33:33" /> <SeekBar android:id="@+id/mediacontroller_seekbar" style="@style/MediaController_SeekBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_toLeftOf="@id/mediacontroller_time_total" android:layout_toRightOf="@id/mediacontroller_time_current" android:focusable="true" android:max="1000" /> RelativeLayout> RelativeLayout>LinearLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
(5)Manifest
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.hx.vitamio"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:screenOrientation="sensorLandscape"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> intent-filter> activity> <activity android:name="io.vov.vitamio.activity.InitActivity" android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation" android:launchMode="singleTop" android:theme="@android:style/Theme.NoTitleBar" android:windowSoftInputMode="stateAlwaysHidden" /> application> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />manifest>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
具体就不一一分析了,大家需要直接看代码吧。
一些电视台的直播地址
下面是我记录的一些电视台的直播地址,奉献给大家:
CCTV: rtmp://203.207.99.19:1935/live/CCTV5
注:后面的数字可以自己修改为中央几台
凤凰卫视:http://zv.3gv.ifeng.com/live/zhongwen800k.m3u8
Demo下载地址
Part1…
Part2…
Part3…
请将三部分全部下载完毕后再进行解压。
- Rexsee API介绍:Android照片、视频拍摄,Camera扩展
- Android本地视频播放器开发--ffmpeg解码视频文件中的音频(1)
- Android中播放GIF动画
- Android(安卓)VideoView如何播放RTSP的流
- Android利用硬解硬编和OpenGLES来高效的处理MP4视频
- 一个使用FFmpeg库读取3gp视频的例子-Android中使用FFmpeg媒体库(
- android之播放多媒体文件一(播放音频)
- android视频桌面源码,酒店应用源码等
- Android音频系统探究——从SoundPool到AudioHardware
随机推荐
-
个人仿制android QQ、android大作业
-
Android开发:android studio启动后,报错:Cou
-
Android获取设备ID、型号及其它信息
-
从android游戏框架看其生命周期!
-
Android 可显示左上右下Drawable的TextVi
-
android字体小结
-
Android中日历控件的使用
-
Android 开发技巧之 手动拖动滚动条快速
-
安卓标签
-
android 开发环境搭建