直播

来源:互联网 发布:网络传输协议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

  1. 依赖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" />

  1. 添加<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" />

  1.  在操作的activity中加入

<category android:name="android.intent.category.DEFAULT" />

  1. 在MyApplication里面初始化

Vitamio.initialize(this);

  1. 两种方式  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