qq_36048445 2019-01-18 15:33
浏览 2325

MediaRecorder录屏,Socket传输录屏内容报错java.lang.IllegalStateException

用模拟器调试可以运行,用真机测试在 mediaRecorder.prepare();抛异常

package www.xjw.com.mymiracast2.screenrecordservice;

import android.app.Notification;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;


import java.net.Socket;



/**
 * Created by dzjin on 2018/1/9.
 */

public class ScreenRecordService extends Service {

    private int resultCode;
    private Intent resultData=null;

    private MediaProjection mediaProjection=null;
    private MediaRecorder mediaRecorder=null;
    private VirtualDisplay virtualDisplay=null;

    private int mScreenWidth;
    private int mScreenHeight;
    private int mScreenDensity;
    private static String filePathName;

    private Socket receiver = null;
    private ParcelFileDescriptor pfd = null;

    private Context context=null;

    private String host = null;
    private int port = 8989;

    @Override
    public void onCreate() {
        super.onCreate();
        //startForeground(2, new Notification());
    }

    /**
     * 每次客户端通过调用startService(Intent)显式启动服务时,系统调用startService(Intent),
      *提供它提供的参数和表示启动请求的唯一整数标记。
     * 不要直接调用这个方法。
     * @param intent
     * @param flags
     * @param startId
     * @return
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        try{
            resultCode=intent.getIntExtra("resultCode",-1);
            resultData=intent.getParcelableExtra("resultData");
            mScreenWidth=intent.getIntExtra("mScreenWidth",0);
            mScreenHeight=intent.getIntExtra("mScreenHeight",0);
            mScreenDensity=intent.getIntExtra("mScreenDensity",0);
            filePathName=intent.getStringExtra("filePathName");
            host=intent.getStringExtra("host");
            port=intent.getIntExtra("port",8989);

            receiver = new Socket(host, port);
            pfd = ParcelFileDescriptor
                    .fromSocket(receiver);

            mediaProjection=createMediaProjection();
            mediaRecorder=createMediaRecorder();
            virtualDisplay=createVirtualDisplay();
            mediaRecorder.start();

        }catch (Exception e) {
            e.printStackTrace();
        }
        /**
         * START_NOT_STICKY:
         *从onStartCommand返回的常量(Intent, int, int):如果这个服务的进程是
         *在启动时被杀死(从onStartCommand(Intent, int, int)返回后),
         *没有新的start意图交付给它,然后将服务从
         *启动状态,在以后显式调用Context.startService(Intent)之前不要重新创建。
         *服务将不会接收带有空意图的onStartCommand(Intent, int, int)调用
         *因为如果没有等待交付的意图,它将不会重新启动。
         */
        return Service.START_NOT_STICKY;
    }

    public MediaProjection createMediaProjection(){
        /**
         *使用getSystemService(类)检索MediaProjectionManager实例
         *管理媒体放映会议。
         */
        return ((MediaProjectionManager)getSystemService(Context.MEDIA_PROJECTION_SERVICE))
                .getMediaProjection(resultCode,resultData);
        /**
         *检索从成功的屏幕捕获请求中获得的MediaProjection。
         *如果startActivityForResult()的结果不是RESULT_OK,则*将为null。
         */
    }

    private MediaRecorder createMediaRecorder(){

        //用于录制音频和视频。录音控制是基于一个简单的状态机。
        MediaRecorder mediaRecorder=new MediaRecorder();
        //设置要录音的源。
        //mediaRecorder.setAudioSource(MediaRecorder. AudioSource.CAMCORDER);
        //设置要录制的视频源。
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        //设置录制过程中产生的输出的格式。
        //3GPP媒体文件格式
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);
        //设置录音格式
        //mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        //设置录像编码比特率。
        //param:以比特/秒为单位的视频编码比特率
        mediaRecorder.setVideoEncodingBitRate(5*mScreenWidth*mScreenHeight);
        //设置录像编码器用于录像。
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        //设置要拍摄的视频的宽度和高度。
        mediaRecorder.setVideoSize(mScreenWidth,mScreenHeight);
        //设置要捕获视频的帧速率。
        mediaRecorder.setVideoFrameRate(60);
        try{
            mediaRecorder.setOutputFile(pfd.getFileDescriptor());
            //mediaRecorder.setOutputFile(filePathName);
                        **此次抛异常**
            //准备记录器开始捕捉和编码数据。
            mediaRecorder.prepare();
        }catch (Exception e){
            e.printStackTrace();
        }
        return mediaRecorder;
    }

    private VirtualDisplay createVirtualDisplay(){
        /**
         *名称字符串:虚拟显示的名称,必须是非空的。这个值不能为空。
         width int:虚拟显示的宽度,以像素为单位。必须大于0。
         高度int:虚拟显示器的高度,以像素为单位。必须大于0。
         dpi int: dpi中虚拟显示的密度。必须大于0。
         标志int:虚拟显示标志的组合。有关标志的完整列表,请参见DisplayManager。
         surface surface:虚拟显示内容应该呈现到的表面,如果一开始没有,则为null。
         回调virtualdisplay。回调:当虚拟显示的状态改变时调用的回调,如果没有,则为空。
         处理程序处理程序:应该在其上调用回调的处理程序,如果应该在调用线程的主循环程序上调用回调,则为null。
         */
        /**
         * DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
         *虚拟显示标志:当没有显示内容时,允许在私有显示上镜像内容。
         */
        return mediaProjection.createVirtualDisplay("mediaProjection",mScreenWidth,mScreenHeight,mScreenDensity,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,mediaRecorder.getSurface(),null,null);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if(virtualDisplay!=null){
            virtualDisplay.release();
            virtualDisplay=null;
        }
        if(mediaRecorder!=null){
            mediaRecorder.stop();
            mediaRecorder=null;
        }
        if(mediaProjection!=null){
            mediaProjection.stop();
            mediaProjection=null;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("===============================");
        return null;
    }

}

I/MediaRecorder: enter in file frameworks/av/media/libmedia/mediarecorder.cpp, function prepare, line 461
I/IMediaRecorder: prepare (BpMediaRecorder client) in file frameworks/av/media/libmedia/IMediaRecorder.cpp, function prepare, line 249
W/com.mymiracast2: type=1400 audit(0.0:104572): avc: denied { read write } for path="socket:[8870267]" dev="sockfs" ino=8870267 scontext=u:r:mediaserver:s0 tcontext=u:r:untrusted_app:s0:c512,c768 tclass=tcp_socket permissive=0
E/MediaRecorder: prepare failed: -38
W/zygote64: Got a deoptimization request on un-deoptimizable method void android.media.MediaRecorder._prepare()
W/System.err: java.lang.IllegalStateException
W/System.err: at android.media.MediaRecorder._prepare(Native Method)
W/System.err: at android.media.MediaRecorder.prepare(MediaRecorder.java:1017)
W/System.err: at www.xjw.com.mymiracast2.screenrecordservice.ScreenRecordService.createMediaRecorder(ScreenRecordService.java:137)
W/System.err: at www.xjw.com.mymiracast2.screenrecordservice.ScreenRecordService.onStartCommand(ScreenRecordService.java:79)
W/System.err: at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4151)
W/System.err: at android.app.ActivityThread.-wrap21(Unknown Source:0)
W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2119)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:108)
W/System.err: at android.os.Looper.loop(Looper.java:166)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7529)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
E/MediaRecorder: SurfaceMediaSource could not be initialized!
W/System.err: java.lang.IllegalStateException: failed to get surface
at android.media.MediaRecorder.getSurface(Native Method)
W/System.err: at www.xjw.com.mymiracast2.screenrecordservice.ScreenRecordService.createVirtualDisplay(ScreenRecordService.java:160)
at www.xjw.com.mymiracast2.screenrecordservice.ScreenRecordService.onStartCommand(ScreenRecordService.java:80)
W/System.err: at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4151)
at android.app.ActivityThread.-wrap21(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2119)
at android.os.Handler.dispatchMessage(Handler.java:108)
W/System.err: at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7529)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
D/StrictMode: StrictMode policy violation; ~duration=7334 ms: android.os.StrictMode$StrictModeNetworkViolation: policy=65543 violation=4
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1466)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:356)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:201)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:183)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:356)
at java.net.Socket.connect(Socket.java:616)
at java.net.Socket.connect(Socket.java:565)
at java.net.Socket.(Socket.java:445)
at java.net.Socket.(Socket.java:217)
at www.xjw.com.mymiracast2.screenrecordservice.ScreenRecordService.onStartCommand(ScreenRecordService.java:74)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4151)
at android.app.ActivityThread.-wrap21(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2119)
at android.os.Handler.dispatchMessage(Handler.java:108)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7529)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
D/StrictMode: StrictMode policy violation; ~duration=7332 ms: android.os.StrictMode$StrictModeNetworkViolation: policy=65543 violation=4


  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 matlab数字图像处理频率域滤波
    • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
    • ¥15 ELGamal和paillier计算效率谁快?
    • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
    • ¥15 ubuntu系统下挂载磁盘上执行./提示权限不够
    • ¥15 Arcgis相交分析无法绘制一个或多个图形
    • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
    • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
    • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
    • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误