@ -2,10 +2,8 @@ package com.xypower.mplive;
import android.Manifest ;
import android.content.Intent ;
import android.content.SharedPreferences ;
import android.content.pm.ActivityInfo ;
import android.content.pm.PackageManager ;
import android.content.res.Configuration ;
import android.hardware.Camera ;
import android.os.Build ;
import android.os.Bundle ;
@ -43,19 +41,17 @@ import java.net.SocketException;
import java.util.List ;
import java.util.Random ;
public class MainActivity extends AppCompatActivity implements RtmpHandler . RtmpListener , SrsRecordHandler . SrsRecordListener , SrsEncodeHandler . SrsEncodeListener {
public class MainActivity extends AppCompatActivity implements RtmpHandler . RtmpListener ,
SrsRecordHandler . SrsRecordListener , SrsEncodeHandler . SrsEncodeListener {
private static final String TAG = "MpLive" ;
public final static int RC_CAMERA = 100 ;
private Button btnPublish ;
private Button btnSwitchCamera ;
private Button btnRecord ;
private Button btnSwitchEncoder ;
private Button btnPause ;
private SharedPreferences sp ;
// private String rtmpUrl = "rtmp://192.168.50.250/live/0";
private String rtmpUrl = "rtmp://127.0.0.1/live/0" ;
private String recPath = Environment . getExternalStorageDirectory ( ) . getPath ( ) + "/test.mp4" ;
@ -69,9 +65,14 @@ public class MainActivity extends AppCompatActivity implements RtmpHandler.RtmpL
private Handler mHandler ;
private int cameraId = 0 ;
private List < CameraItemData > cameraData ;
private int rotation ;
private int autoClose ;
private int autoStart ;
private static final int DELAY_MILLIS = 600000 ; // 延迟5分钟
private int netCamera ;
private EditText efu ;
public static final String CUSTOM_ACTION = "com.xypower.mpapp.ACT_TP_M" ;
private int channel ;
@Override
protected void onCreate ( Bundle savedInstanceState ) {
@ -81,25 +82,26 @@ public class MainActivity extends AppCompatActivity implements RtmpHandler.RtmpL
getWindow ( ) . addFlags ( WindowManager . LayoutParams . FLAG_KEEP_SCREEN_ON ) ;
getWindow ( ) . addFlags ( WindowManager . LayoutParams . FLAG_ALT_FOCUSABLE_IM ) ;
setContentView ( R . layout . activity_main ) ;
// 关键代码: 声明为前台可见( Android 10+)
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . Q ) {
setTurnScreenOn ( true ) ; // 唤醒屏幕(即使无物理屏)
setShowWhenLocked ( true ) ; // 允许锁屏显示
}
// response screen rotation event
setRequestedOrientation ( ActivityInfo . SCREEN_ORIENTATION_FULL_SENSOR ) ;
requestPermission ( ) ;
Intent intent = getIntent ( ) ;
int overtime = intent . getIntExtra ( "overtime" , DELAY_MILLIS ) ;
mHandler . postDelayed ( new Runnable ( ) {
@Override
public void run ( ) {
finish ( ) ;
}
} , overtime ) ;
}
private void requestPermission ( ) {
//1. 检查是否已经有该权限
if ( Build . VERSION . SDK_INT > = 23 & & ( ContextCompat . checkSelfPermission ( this , Manifest . permission . CAMERA ) ! = PackageManager . PERMISSION_GRANTED | | ContextCompat . checkSelfPermission ( this , Manifest . permission . RECORD_AUDIO ) ! = PackageManager . PERMISSION_GRANTED | | ContextCompat . checkSelfPermission ( this , Manifest . permission . WRITE_EXTERNAL_STORAGE ) ! = PackageManager . PERMISSION_GRANTED ) ) {
if ( Build . VERSION . SDK_INT > = 23 & & ( ContextCompat . checkSelfPermission ( this , Manifest . permission . CAMERA )
! = PackageManager . PERMISSION_GRANTED | | ContextCompat . checkSelfPermission ( this , Manifest . permission . RECORD_AUDIO )
! = PackageManager . PERMISSION_GRANTED | | ContextCompat . checkSelfPermission ( this , Manifest . permission . WRITE_EXTERNAL_STORAGE )
! = PackageManager . PERMISSION_GRANTED ) ) {
//2. 权限没有开启,请求权限
ActivityCompat . requestPermissions ( this , new String [ ] { Manifest . permission . CAMERA , Manifest . permission . RECORD_AUDIO , Manifest . permission . WRITE_EXTERNAL_STORAGE } , RC_CAMERA ) ;
ActivityCompat . requestPermissions ( this ,
new String [ ] { Manifest . permission . CAMERA , Manifest . permission . RECORD_AUDIO , Manifest . permission . WRITE_EXTERNAL_STORAGE } , RC_CAMERA ) ;
} else {
//权限已经开启,做相应事情
isPermissionGranted = true ;
@ -111,6 +113,12 @@ public class MainActivity extends AppCompatActivity implements RtmpHandler.RtmpL
}
}
private void init ( ) {
initView ( ) ;
initIntent ( ) ;
initEvent ( ) ;
}
//3. 接收申请成功或者失败回调
@Override
public void onRequestPermissionsResult ( int requestCode , String [ ] permissions , int [ ] grantResults ) {
@ -131,120 +139,65 @@ public class MainActivity extends AppCompatActivity implements RtmpHandler.RtmpL
}
}
private void init ( ) {
private void initIntent ( ) {
Intent intent = getIntent ( ) ;
final int autoStart = intent . getIntExtra ( "autoStart" , 1 ) ;
final int netCamera = intent . getIntExtra ( "netCamera" , 0 ) ;
final int vendor = intent . getIntExtra ( "vendor" , 0 ) ;
final int disableLocalServer = intent . getIntExtra ( "disableLocalServer" , 0 ) ;
final int rotation = intent . getIntExtra ( "rotation" , - 1 ) ;
int autoClose = intent . getIntExtra ( "autoClose" , 0 ) ;
// restore data.
sp = getSharedPreferences ( "MpLive" , MODE_PRIVATE ) ;
// rtmpUrl = sp.getString("rtmpUrl", rtmpUrl);
// initialize url.
final EditText efu = ( EditText ) findViewById ( R . id . url ) ;
btnPublish = ( Button ) findViewById ( R . id . publish ) ;
btnSwitchCamera = ( Button ) findViewById ( R . id . swCam ) ;
btnRecord = ( Button ) findViewById ( R . id . record ) ;
btnSwitchEncoder = ( Button ) findViewById ( R . id . swEnc ) ;
btnPause = ( Button ) findViewById ( R . id . pause ) ;
btnPause . setEnabled ( false ) ;
mCameraView = ( SrsCameraView ) findViewById ( R . id . glsurfaceview_camera ) ;
autoStart = intent . getIntExtra ( "autoStart" , 1 ) ;
String url = intent . getStringExtra ( "url" ) ;
if ( ! TextUtils . isEmpty ( url ) ) {
rtmpUrl = url ;
}
if ( TextUtils . isEmpty ( rtmpUrl ) ) {
rtmpUrl = "rtmp://127.0.0.1/live/0" ;
}
efu. setText ( rtmpUrl ) ;
rotation = intent . getIntExtra ( "rotation" , - 1 ) ;
if ( autoStart ! = 0 ) {
cameraId = intent . getIntExtra ( "cameraId" , 0 ) ;
if ( disableLocalServer = = 0 ) {
startRTMPServer ( ) ;
}
}
autoClose = intent . getIntExtra ( "autoClose" , 0 ) ;
if ( netCamera ! = 0 ) {
netCamera = intent . getIntExtra ( "netCamera" , 0 ) ;
} else {
if ( rotation ! = - 1 ) {
//设置图像显示方向
mCameraView . setPreviewOrientation ( rotation ) ;
}
cameraData = mCameraView . getCameraData ( ) ;
int size = cameraData . size ( ) ;
if ( size = = 0 ) {
Toast . makeText ( getApplicationContext ( ) , "没有查询到摄像头" , Toast . LENGTH_SHORT ) . show ( ) ;
}
mPublisher = new SrsPublisher ( mCameraView ) ;
mPublisher . setEncodeHandler ( new SrsEncodeHandler ( this ) ) ;
mPublisher . setRtmpHandler ( new RtmpHandler ( this ) ) ;
mPublisher . setRecordHandler ( new SrsRecordHandler ( this ) ) ;
channel = intent . getIntExtra ( "channel" , 0 ) ;
}
mPublisher . setPreviewResolution ( mWidth , mHeight ) ; //设置预览宽高
mPublisher . setOutputResolution ( mHeight , mWidth ) ; // 这里要和preview反过来
private void initView ( ) {
btnPublish = ( Button ) findViewById ( R . id . publish ) ;
btnSwitchCamera = ( Button ) findViewById ( R . id . swCam ) ;
btnRecord = ( Button ) findViewById ( R . id . record ) ;
btnSwitchEncoder = ( Button ) findViewById ( R . id . swEnc ) ;
btnPause = ( Button ) findViewById ( R . id . pause ) ;
btnPause . setEnabled ( false ) ;
mPublisher . setVideoHDMode ( ) ;
efu = ( EditText ) findViewById ( R . id . url ) ;
efu . setText ( rtmpUrl ) ;
cameraId = intent . getIntExtra ( "cameraId" , 0 ) ;
// mPublisher.startCamera();
mCameraView = ( SrsCameraView ) findViewById ( R . id . glsurfaceview_camera ) ;
mCameraView . setCameraCallbacksHandler ( new SrsCameraView . CameraCallbacksHandler ( ) {
@Override
public void onCameraParameters ( Camera . Parameters params ) {
Log . e ( "fsfs" , "fsdf" ) ;
}
} ) ;
if ( autoStart ! = 0 ) {
mPublisher . switchCameraFace ( cameraId , rotation ) ;
mHandler . postDelayed ( new Runnable ( ) {
@Override
public void run ( ) {
// rtmpUrl = "rtmp://61.169.135.146/live/0";
SharedPreferences . Editor editor = sp . edit ( ) ;
editor . putString ( "rtmpUrl" , rtmpUrl ) ;
editor . apply ( ) ;
efu . setText ( rtmpUrl + "rotation= " + rotation + " cameraid=" + cameraId + " auto=" + autoStart ) ;
// efu.setText(rtmpUrl + " cameraid=" + cameraId + " auto=" + autoStart);
efu . setText ( rtmpUrl ) ;
mPublisher . startPublish ( rtmpUrl ) ;
if ( btnSwitchEncoder . getText ( ) . toString ( ) . contentEquals ( "soft encoder" ) ) {
// Toast.makeText(getApplicationContext(), "Use hard encoder", Toast.LENGTH_SHORT).show();
} else {
Toast . makeText ( getApplicationContext ( ) , "Use soft encoder" , Toast . LENGTH_SHORT ) . show ( ) ;
}
btnPublish . setText ( "stop" ) ;
btnSwitchEncoder . setEnabled ( false ) ;
btnPause . setEnabled ( true ) ;
}
} , 500 ) ;
} else {
mPublisher . switchCameraFace ( cameraId , rotation ) ;
}
if ( rotation ! = - 1 ) {
//设置图像显示方向
mCameraView . setPreviewOrientation ( rotation ) ;
}
cameraData = mCameraView . getCameraData ( ) ;
int size = cameraData . size ( ) ;
if ( size = = 0 ) {
Toast . makeText ( getApplicationContext ( ) , "没有查询到摄像头" , Toast . LENGTH_SHORT ) . show ( ) ;
}
mPublisher = new SrsPublisher ( mCameraView ) ;
mPublisher . setEncodeHandler ( new SrsEncodeHandler ( this ) ) ;
mPublisher . setRtmpHandler ( new RtmpHandler ( this ) ) ;
mPublisher . setRecordHandler ( new SrsRecordHandler ( this ) ) ;
mPublisher . setPreviewResolution ( mWidth , mHeight ) ; //设置预览宽高
mPublisher . setOutputResolution ( mHeight , mWidth ) ; // 这里要和preview反过来
if ( autoClose ! = 0 ) {
mHandler . postDelayed ( new Runnable ( ) {
@Override
public void run ( ) {
Log . w ( TAG , "Close self automatically" ) ;
finish ( ) ;
System . exit ( 0 ) ;
}
} , 1000 ) ;
}
mPublisher . setVideoHDMode ( ) ;
mCameraView . setCameraCallbacksHandler ( new SrsCameraView . CameraCallbacksHandler ( ) {
@Override
public void onCameraParameters ( Camera . Parameters params ) {
Log . e ( "fsfs" , "fsdf" ) ;
}
} ) ;
btnPublish . setOnClickListener ( new View . OnClickListener ( ) {
@Override
@ -254,12 +207,8 @@ public class MainActivity extends AppCompatActivity implements RtmpHandler.RtmpL
Toast . makeText ( getApplicationContext ( ) , "没有正确的推送地址" , Toast . LENGTH_SHORT ) . show ( ) ;
return ;
}
SharedPreferences . Editor editor = sp . edit ( ) ;
editor . putString ( "rtmpUrl" , rtmpUrl ) ;
editor . apply ( ) ;
efu . setText ( rtmpUrl ) ;
mPublisher . startPublish ( rtmpUrl ) ;
// mPublisher.startCamera();
mPublisher . switchCameraFace ( cameraId , rotation ) ;
if ( btnSwitchEncoder . getText ( ) . toString ( ) . contentEquals ( "soft encoder" ) ) {
@ -335,6 +284,64 @@ public class MainActivity extends AppCompatActivity implements RtmpHandler.RtmpL
} ) ;
}
private void initEvent ( ) {
if ( autoStart = = 1 ) {
startRTMPServer ( ) ;
mHandler . postDelayed ( new Runnable ( ) {
@Override
public void run ( ) {
// rtmpUrl = "rtsp://127.0.0.1:8554/live/7";
efu . setText ( rtmpUrl + " rotation= " + rotation + " cameraid=" + cameraId + " auto=" + autoStart ) ;
if ( netCamera = = 0 ) {
mPublisher . startPublish ( rtmpUrl ) ;
if ( btnSwitchEncoder . getText ( ) . toString ( ) . contentEquals ( "soft encoder" ) ) {
// Toast.makeText(getApplicationContext(), "Use hard encoder", Toast.LENGTH_SHORT).show();
} else {
Toast . makeText ( getApplicationContext ( ) , "Use soft encoder" , Toast . LENGTH_SHORT ) . show ( ) ;
}
btnPublish . setText ( "stop" ) ;
btnSwitchEncoder . setEnabled ( false ) ;
btnPause . setEnabled ( true ) ;
mPublisher . switchCameraFace ( cameraId , rotation ) ;
} else {
sendStartPushBroadcast ( ) ;
}
}
} , 500 ) ;
} else {
mPublisher . switchCameraFace ( cameraId , rotation ) ;
}
if ( autoClose ! = 0 ) {
mHandler . postDelayed ( new Runnable ( ) {
@Override
public void run ( ) {
Log . w ( TAG , "Close self automatically" ) ;
finish ( ) ;
System . exit ( 0 ) ;
}
} , 100000 ) ;
}
}
private void sendStartPushBroadcast ( ) {
Log . d ( "开始发送广播" , rtmpUrl ) ;
Intent intent = new Intent ( CUSTOM_ACTION ) ;
intent . putExtra ( "Channel" , channel ) ;
intent . putExtra ( "MediaType" , 16 ) ;
intent . putExtra ( "Url" , rtmpUrl ) ;
sendBroadcast ( intent ) ;
}
private void sendStopPushBroadcast ( ) {
Intent intent = new Intent ( CUSTOM_ACTION ) ;
intent . putExtra ( "Channel" , channel ) ;
intent . putExtra ( "MediaType" , 17 ) ;
intent . putExtra ( "Url" , rtmpUrl ) ;
sendBroadcast ( intent ) ;
}
@Override
public boolean onCreateOptionsMenu ( Menu menu ) {
// Inflate the menu; this adds items to the action bar if it is present.
@ -419,8 +426,6 @@ public class MainActivity extends AppCompatActivity implements RtmpHandler.RtmpL
@Override
protected void onResume ( ) {
super . onResume ( ) ;
final Button btn = ( Button ) findViewById ( R . id . publish ) ;
btn . setEnabled ( true ) ;
mPublisher . resumeRecord ( ) ;
}
@ -433,27 +438,32 @@ public class MainActivity extends AppCompatActivity implements RtmpHandler.RtmpL
@Override
protected void onDestroy ( ) {
super . onDestroy ( ) ;
// mPublisher.stopEncode();
if ( netCamera = = 1 ) {
sendStopPushBroadcast ( ) ;
}
stopRTMPServer ( ) ;
mPublisher . stopPublish ( ) ;
mPublisher . stopRecord ( ) ;
stopRTMPServer ( ) ;
}
@Override
public void onConfigurationChanged ( Configuration newConfig ) {
super . onConfigurationChanged ( newConfig ) ;
mPublisher . stopEncode ( ) ;
mPublisher . stopRecord ( ) ;
btnRecord . setText ( "record" ) ;
mPublisher . setScreenOrientation ( newConfig . orientation ) ;
if ( btnPublish . getText ( ) . toString ( ) . contentEquals ( "stop" ) ) {
mPublisher . startEncode ( ) ;
}
mPublisher . startCamera ( ) ;
}
// @Override
// public void onConfigurationChanged(Configuration newConfig) {
// super.onConfigurationChanged(newConfig);
// mPublisher.stopEncode();
// mPublisher.stopRecord();
// btnRecord.setText("record");
// mPublisher.setScreenOrientation(newConfig.orientation);
// if (btnPublish.getText().toString().contentEquals("stop")) {
// mPublisher.startEncode();
// }
// mPublisher.startCamera();
// }
private void startRTMPServer ( ) {
File streamingDir = new File ( getDataDir ( ) , "streaming" ) ;
File streamingDir = null ;
if ( android . os . Build . VERSION . SDK_INT > = android . os . Build . VERSION_CODES . N ) {
streamingDir = new File ( getDataDir ( ) , "streaming" ) ;
}
if ( ! streamingDir . exists ( ) ) {
streamingDir . mkdirs ( ) ;
}