直播
来源:互联网 发布:网络传输协议arp 编辑:程序博客网 时间:2024/04/25 20:30
Vitamio 视频直播播放端
- MediaPlayer:https://www.vitamio.org/docs/API/2013/0508/10.html
- VideoView:https://www.vitamio.org/docs/API/2013/0508/9.html
- 依赖module—vitamio (注意raw文件夹)
权限配置
<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.WRITE_EXTERNAL_STORAGE" />
- 添加<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" />
- 在操作的activity中加入
<category android:name="android.intent.category.DEFAULT" />
- 在MyApplication里面初始化
Vitamio.initialize(this);
- 两种方式 MainActivity.java
- ①使用MediaPlayer(用于播放rtmp)
public class MainActivity extends AppCompatActivity { String url = "rtmp://live.hkstv.hk.lxdns.com/live/hks"; SurfaceView surfaceView; MediaPlayer mediaPlayer; //vitamio下的类 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); surfaceView = (SurfaceView) findViewById(sv); surfaceView.getHolder().addCallback(callback); surfaceView.getHolder().setFormat(PixelFormat.RGBA_8888); //画质(必加) surfaceView.setOnClickListener(onClickListener); } SurfaceHolder.Callback callback = new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { try { mediaPlayer = new MediaPlayer(getBaseContext()); mediaPlayer.setDataSource(url); mediaPlayer.setDisplay(holder); mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mediaPlayer.start(); } }); mediaPlayer.prepareAsync(); mediaPlayer.setBufferSize(1024 * 1024 * 2); //设置缓存大小 } catch (IOException e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { if (mediaPlayer != null) { if (mediaPlayer.isPlaying()) { mediaPlayer.stop(); } mediaPlayer.release(); mediaPlayer = null; } } }; //点击画面暂停或者播放 View.OnClickListener onClickListener = new View.OnClickListener() { @Override public void onClick(View v) { if (mediaPlayer != null) { if (mediaPlayer.isPlaying()) { mediaPlayer.pause(); Toast.makeText(MainActivity.this, "已暂停", Toast.LENGTH_SHORT).show(); } else { mediaPlayer.start(); Toast.makeText(MainActivity.this, "继续播放", Toast.LENGTH_SHORT).show(); } } } };}
- ②使用VideoView(用于播放flv)
public class FlvActivity extends AppCompatActivity { VideoView videoView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_flv); videoView = (VideoView) findViewById(R.id.vv); MediaController controller = new MediaController(this); videoView.setMediaController(controller); videoView.setVideoPath("http://pull99.a8.com/live/1482127743567166.flv"); videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); } }); }}
百度云直播(视频录制端)
https://cloud.baidu.com/doc/LSS/Android-Capture-SDK.html#.E5.BC.80.E5.A7.8B.E6.8E.A8.E6.B5.81
/*** Session:开会,会议;(法庭的)开庭;会期,学期;(进行某活动连续的)一段时间*/public class MainActivity extends AppCompatActivity implements View.OnClickListener { LiveSession liveSession; SurfaceView surfaceView; Button btnFlash; Button btnBegin; Button btnSwitchCamera; boolean isPrepare; boolean isError = false; //是否出错 boolean isPlaying = false; //是否播放 boolean isOpenFlash = false;//是否开启闪光灯 int cameraState = 0; //前置或后置摄像头 public static final int[] STATE = {LiveConfig.CAMERA_FACING_BACK, LiveConfig.CAMERA_FACING_FRONT}; //0后置 1前置 String url = "rtmp://zhibo1.whunf.com.cn/xykj/push"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initLiveSession(); surfaceView = (SurfaceView) findViewById(R.id.sv); btnBegin = (Button) findViewById(R.id.btn_begin); btnFlash = (Button) findViewById(R.id.btn_flash); btnSwitchCamera = (Button) findViewById(R.id.btn_switchCamera); btnBegin.setOnClickListener(this); btnFlash.setOnClickListener(this); btnSwitchCamera.setOnClickListener(this); } private void initLiveSession() { //初始化 LiveSession LiveConfig liveConfig = new LiveConfig.Builder() .setCameraId(LiveConfig.CAMERA_FACING_FRONT) // 选择摄像头为前置摄像头 .setCameraOrientation(LiveConfig.CAMERA_FACING_BACK) // 设置摄像头为竖向 .setVideoWidth(1280) // 设置推流视频宽度, 需传入长的一边 .setVideoHeight(720) // 设置推流视频高度,需传入短的一边 .setVideoFPS(30) // 设置视频帧率 .setInitVideoBitrate(1200) // 设置视频码率,单位为bit per seconds .setAudioBitrate(64 * 1000) // 设置音频码率,单位为bit per seconds .setAudioSampleRate(LiveConfig.AUDIO_SAMPLE_RATE_44100) // 设置音频采样率 .setGopLengthInSeconds(2) // 设置I帧间隔,单位为秒 .setQosEnabled(true) // 开启码率自适应,默认为true,即默认开启 .setMinVideoBitrate(200 * 1000) // 码率自适应,最低码率 .setMaxVideoBitrate(1024 * 1000) // 码率自适应,最高码率 .setQosSensitivity(5) // 码率自适应,调整的灵敏度,单位为秒,可接受[5, 10]之间的整数值 .build(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { //版本大于或等于4.3 liveSession = new LiveSessionHW(this, liveConfig); } else { liveSession = new LiveSessionSW(this, liveConfig); } liveSession.setStateListener(sessionStateListener); //liveSession状态监听 liveSession.bindPreviewDisplay(surfaceView.getHolder()); //初始化成功后,必须为LiveSession对象设置预览View,否则无法启动相机 liveSession.prepareSessionAsync(); //在开始推流前,需要启动音视频采集设备(即相机和 MIC) } SessionStateListener sessionStateListener = new SessionStateListener() { @Override public void onSessionPrepared(int i) { //已准备好 isPrepare = true; } @Override public void onSessionStarted(int i) { //开始 } @Override public void onSessionStopped(int i) { //停止 } @Override public void onSessionError(int i) { //出错 isError = true; switch (i) { case ERROR_CODE_OF_OPEN_MIC_FAILED: Toast.makeText(MainActivity.this, "MIC设备无法打开", Toast.LENGTH_SHORT).show(); break; case ERROR_CODE_OF_OPEN_CAMERA_FAILED: Toast.makeText(MainActivity.this, "相机设备无法打开", Toast.LENGTH_SHORT).show(); break; case ERROR_CODE_OF_PREPARE_SESSION_FAILED: Toast.makeText(MainActivity.this, "接口调用失败,原因只能是 MIC 或相机打开失败", Toast.LENGTH_SHORT).show(); break; case ERROR_CODE_OF_CONNECT_TO_SERVER_FAILED: Toast.makeText(MainActivity.this, "原因通常为连接不上推流服务器", Toast.LENGTH_SHORT).show(); break; case ERROR_CODE_OF_DISCONNECT_FROM_SERVER_FAILED: Toast.makeText(MainActivity.this, "网路异常", Toast.LENGTH_SHORT).show(); break; } } }; @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_begin: //播放/暂停 if (isPrepare && !isError) { //若已准备好且没有出错 if (isPlaying) { //如果正在播放 liveSession.startRtmpSession(url); //开始url btnBegin.setText("停止"); } else { liveSession.stopRtmpSession(); //如果没有播放,则停止url btnBegin.setText("开始"); } } else if (isError) { Toast.makeText(MainActivity.this, "推流出错", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MainActivity.this, "正在准备推流", Toast.LENGTH_SHORT).show(); } break; case R.id.btn_flash:// if (STATE[cameraState % 2] == 1) {// btnFlash.setEnabled(false);// } else {// btnFlash.setEnabled(true);// } isOpenFlash = !isOpenFlash; liveSession.toggleFlash(isOpenFlash); //开启闪光灯 break; case R.id.btn_switchCamera: if (liveSession.canSwitchCamera()) { cameraState++; liveSession.switchCamera(STATE[cameraState % 2]); //0则后置,1则前置// if (isOpenFlash && (cameraState % 2 == 1)) { //当开了闪光灯,且前置的时候// isOpenFlash = false;// } } break; } } @Override public void onBackPressed() { //退出时候,关闭session super.onBackPressed(); liveSession.stopRtmpSession(); }}
0 0
- 直播
- 直播
- 直播
- 直播
- 直播-提升直播成功率
- 直播与虚拟直播
- 直播程序直播系统,云豹直播提供优质服务
- 视频直播
- 奥运直播
- live555直播
- 直播画中画
- 直播+录播
- 视频直播
- Live555 直播
- live555 直播
- V直播
- 直播地址
- iOS直播
- C语言-结构体-1887 候选人得票统计
- UML类图常见的几种关系
- EasyUI的引入和使用
- Linux投石问路
- 图像的点运算
- 直播
- websocket + html (聊天室) 补上次遗留的一个 强制关闭报error错误
- reinterpret_cast,static_cast,dynamic_cast,const_cast类型转换
- linux下查看所有用户及所有用户组
- Windows server 2008 R2查看当前连接数
- iOS 如何创建可以带参数的宏定义
- TVS2.0
- 纹理
- 仿Airbnb登录界面提示组件