秋风落叶黄 2021-12-03 15:53 采纳率: 0%
浏览 25
已结题

Android录制屏幕功能手机版本高于8.0报stop failed错误

下面是录屏的代码,同样的程序在安卓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)

  • 写回答

2条回答 默认 最新

  • 有问必答小助手 2021-12-06 10:22
    关注

    你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答


    本次提问扣除的有问必答次数,已经为您补发到账户,我们后续会持续优化,扩大我们的服务范围,为您带来更好地服务。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 12月18日
  • 已采纳回答 12月10日
  • 创建了问题 12月3日

悬赏问题

  • ¥50 MATLAB APP 制作出现问题
  • ¥15 wannier复现图像时berry曲率极值点与高对称点严重偏移
  • ¥15 利用决策森林为什么会出现这样·的问题(关键词-情感分析)
  • ¥15 DispatcherServlet.noHandlerFound No mapping found for HTTP request with URI[/untitled30_war_e
  • ¥15 使用deepspeed训练,发现想要训练的参数没有梯度
  • ¥15 寻找一块做为智能割草机的驱动板(标签-stm32|关键词-m3)
  • ¥15 信息管理系统的查找和排序
  • ¥15 基于STM32,电机驱动模块为L298N,四路运放电磁传感器,三轮智能小车电磁组电磁循迹(两个电机,一个万向轮),怎么用读取的电磁传感器信号表示小车所在的位置
  • ¥15 如何解决y_true和y_predict数据类型不匹配的问题(相关搜索:机器学习)
  • ¥15 PB中矩阵文本型数据的总计问题。