下面是录屏的代码,同样的程序在安卓8.0上运行没有问题,但是在9.0上运行回报stop failed导致录的视频无法播放。
我把这个功能代码单独写一个APP在同一个9.0手机上运行也没有问题,把功能写在项目里就不行,这是什么原因造成的。
用的9.0手机是华为nova3 ,8.0用的vivo。求解决办法。
public class ScreenService extends Service implements MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener{
private MediaRecorder mediaRecorder;
private VirtualDisplay virtualDisplay;
private boolean running;
private int width = 720;
private int height = 1280;
private int dpi;
private ImageReader mImageReader;
private MediaProjection mediaProjection;
@Override
public IBinder onBind(Intent intent) {
return new RecordBinder();
}
@Override
public void onCreate() {
super.onCreate();
running = false;
Log.d("789789", "ScreenService==onCreate()");
mediaRecorder = new MediaRecorder();
mediaRecorder.setOnErrorListener(this);
mediaRecorder.setOnInfoListener(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
public void setMediaProject(MediaProjection project) {
mediaProjection = project;
}
public boolean isRunning() {
return running;
}
public void setConfig(int width, int height, int dpi) {
this.width = width;
this.height = height;
this.dpi = dpi;
}
public void stopMediaRecorder(){
stopRecord();
}
/**
* 开始录屏
*
* @return true
*/
public boolean startRecord() {
Log.d("789789","11111");
if (mediaProjection == null || running) {
Log.d("789789","222222");
return false;
}
initRecorder();
Log.d("789789","44444444");
createVirtualDisplay();
Log.d("789789","6666666");
mediaRecorder.start();
Log.d("789789","开始");
running = true;
return true;
}
/**
* 结束录屏
*
* @return true
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
public boolean stopRecord() {
if (!running) {
Log.d("789789","没有运行");
return false;
}
Log.d("789789","结束运行");
running = false;
try {
mediaRecorder.setOnErrorListener(null);
mediaRecorder.setOnInfoListener(null);
mediaRecorder.setPreviewDisplay(null);
mediaRecorder.stop();
} catch (IllegalStateException e) {
// TODO: handle exception
Log.i("789789", Log.getStackTraceString(e));
}catch (RuntimeException e) {
// TODO: handle exception
Log.i("789789", Log.getStackTraceString(e));
}catch (Exception e) {
// TODO: handle exception
Log.i("789789", Log.getStackTraceString(e));
}
mediaRecorder.reset();
virtualDisplay.release();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mediaProjection.stop();
}
return true;
}
// public void setMediaProjection(MediaProjection mediaProjection) {
// this.mediaProjection = mediaProjection;
// }
/**
* 初始化ImageRead参数
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
public void initImageReader() {
if (mImageReader == null) {
int maxImages = 2;
mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, maxImages);
createImageVirtualDisplay();
}
}
/**
* 创建一个录屏 Virtual
*/
private void createVirtualDisplay() {
Log.d("789789","5555555");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
virtualDisplay = mediaProjection
.createVirtualDisplay("mediaprojection", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder
.getSurface(), null, null);
}
}
/**
* 创建一个ImageReader Virtual
*/
private void createImageVirtualDisplay() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
virtualDisplay = mediaProjection.createVirtualDisplay("mediaprojection", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader.getSurface(), null, null);
}
}
/**
* 初始化保存屏幕录像的参数
*/
@TargetApi(Build.VERSION_CODES.FROYO)
private void initRecorder() {
Log.d("789789","3333333");
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncodingBitRate(96000); //设置编码频率
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setVideoSize(width, height);
mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);
mediaRecorder.setVideoFrameRate(30);
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
mediaRecorder.setOutputFile(getSavePath() + simpleDateFormat.format(new Date()) + ".mp4");
try {
mediaRecorder.prepare();
Log.d("789789","准备就绪");
} catch (IOException e) {
e.printStackTrace();
Log.d("789789","准备失败");
}
}
/**
* 获取一个保存屏幕录像的路径
*
* @return path
*/
public String getSavePath() {
if (Environment.getExternalStorageState()
.equals(Environment.MEDIA_MOUNTED)) {
String rootDir = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/" +
"DroneVideo" + "/";
File file = new File(rootDir);
if (!file.exists()) {
if (!file.mkdirs()) {
return null;
}
}
return rootDir;
} else {
return null;
}
}
/**
* 请求完权限后马上获取有可能为null,可以通过判断is null来重复获取。
*/
public Bitmap getBitmap() {
Bitmap bitmap = cutoutFrame();
if (bitmap == null) {
getBitmap();
}
return bitmap;
}
/**
* 通过底层来获取下一帧的图像
*
* @return bitmap
*/
@TargetApi(Build.VERSION_CODES.KITKAT)
public Bitmap cutoutFrame() {
Image image = mImageReader.acquireLatestImage();
if (image == null) {
return null;
}
int width = image.getWidth();
int height = image.getHeight();
final Image.Plane[] planes = image.getPlanes();
final ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * width;
Bitmap bitmap = Bitmap.createBitmap(width +
rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
return Bitmap.createBitmap(bitmap, 0, 0, width, height);
}
@Override
public void onError(MediaRecorder mr, int what, int extra) {
System.out.println("onError,what=="+what+",extra=="+extra);
}
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
System.out.println("onInfo,what=="+what+",extra=="+extra);
}
public class RecordBinder extends Binder {
public ScreenService getRecordService() {
return ScreenService.this;
}
}
}
/////////////////////报错信息//////////////////////////////
2021-12-03 15:47:39.542 25249-25249/? I/B_Exception: java.lang.RuntimeException: stop failed.
at android.media.MediaRecorder.native_stop(Native Method)
at android.media.MediaRecorder.stop(MediaRecorder.java:1610)
at com.dji.FPVDemo.ScreenService.stopRecord(ScreenService.java:136)
at com.dji.FPVDemo.MainActivity.stopScreenRecord(MainActivity.java:1405)
at com.dji.FPVDemo.MainActivity.cameraSend(MainActivity.java:1288)
at com.dji.FPVDemo.MainActivity.onClick(MainActivity.java:1261)
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:5683)
at android.view.View.performClick(View.java:6659)
at android.view.View.performClickInternal(View.java:6631)
at android.view.View.access$3100(View.java:790)
at android.view.View$PerformClick.run(View.java:26187)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)