get ERROR_CAMERA_ALREADY_IN_USE when usb debugging

2019-09-17 18:10发布

问题:

I am trying to use libstreaming library to stream my phone camera output. I built my app based on the Example 3. But I just keep getting this ERROR_CAMERA_ALREADY_IN_USE exception when usb debugging with my Nexus 5 (with Android 6.0.1). I tried killing other apps, rebooting my phone, but the exception is still there. I checked online and see this, but it doesnt give me the correct answer. So I am trying to ask for help and I am grateful for any replies. Here is my MainActivity:

import android.app.Activity;
import android.content.SharedPreferences;
import android.hardware.Camera;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.Window;
import android.view.WindowManager;

import net.majorkernelpanic.streaming.Session;
import net.majorkernelpanic.streaming.SessionBuilder;
import net.majorkernelpanic.streaming.audio.AudioQuality;
import net.majorkernelpanic.streaming.gl.SurfaceView;
import net.majorkernelpanic.streaming.rtsp.RtspClient;
import net.majorkernelpanic.streaming.video.VideoQuality;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MainActivity extends Activity implements
        RtspClient.Callback,
        Session.Callback,
        SurfaceHolder.Callback{

    public final static String TAG = "MainActivity";

    private SurfaceView mSurfaceView;
    private Session mSession;
    private RtspClient mClient;
    private final static String mURI = "rtsp://wowzaipaddress:1935/live/test.stream";
    private final static String mUsername = "";
    private final static String mPassword = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "onCreate()");

        mSurfaceView = (SurfaceView) findViewById(R.id.surface);

        mSession = SessionBuilder.getInstance()
                .setContext(getApplicationContext())
                .setAudioEncoder(SessionBuilder.AUDIO_AAC)
                .setAudioQuality(new AudioQuality(8000, 16000))
                .setVideoEncoder(SessionBuilder.VIDEO_H264)
                .setSurfaceView(mSurfaceView)
                .setPreviewOrientation(0)
                .setCallback(this)
                .setCamera(Camera.CameraInfo.CAMERA_FACING_BACK) //CAMERA_FACING_FRONT
                .build();

        // Configures the RTSP client
        mClient = new RtspClient();
        mClient.setSession(mSession);
        mClient.setCallback(this);

        mSurfaceView.getHolder().addCallback(this);
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        mClient.release();
        mSession.release();
        mSurfaceView.getHolder().removeCallback(this);
    }

    @Override
    public void onRtspUpdate(int message, Exception exception) {
        switch (message) {
            case RtspClient.ERROR_CONNECTION_FAILED:
                Log.d(TAG, "Error (ERROR_CONNECTION_FAILED) : " + exception.getMessage());
                break;
            case RtspClient.ERROR_WRONG_CREDENTIALS:
                Log.d(TAG, "Error (ERROR_WRONG_CREDENTIALS) : " + exception.getMessage());
                break;
        }
        exception.printStackTrace();
    }

    /**
     *
     * Session.Callback
     * @param bitrate
     */
    @Override
    public void onBitrateUpdate(long bitrate) {
        Log.d(TAG, "onBitrateUpdate: bit rate change to " + bitrate / 1000 + " kbps");
    }

    @Override
    public void onPreviewStarted() {}

    @Override
    public void onSessionConfigured() {
        mSession.start();
    }

    @Override
    public void onSessionStarted() {

    }

    @Override
    public void onSessionStopped() {}

    @Override
    public void onSessionError(int reason, int streamType, Exception exception) {

        String errorTypeString = "";
        switch (reason) {
            case Session.ERROR_CAMERA_ALREADY_IN_USE:
                errorTypeString = "ERROR_CAMERA_ALREADY_IN_USE";
                break;
            case Session.ERROR_CAMERA_HAS_NO_FLASH:
                errorTypeString = "ERROR_CAMERA_HAS_NO_FLASH";
                break;
            case Session.ERROR_INVALID_SURFACE:
                errorTypeString = "ERROR_INVALID_SURFACE";
                break;
            case Session.ERROR_STORAGE_NOT_READY:
                errorTypeString = "ERROR_STORAGE_NOT_READY";
                break;
            case Session.ERROR_CONFIGURATION_NOT_SUPPORTED:
                VideoQuality quality = mSession.getVideoTrack().getVideoQuality();
                errorTypeString = "ERROR_CONFIGURATION_NOT_SUPPORTED: quality.toString()";
                return;
            case Session.ERROR_OTHER:
                errorTypeString = "ERROR_OTHER";
                break;
        }

        Log.d(TAG, "onSessionError: reason " + errorTypeString);

        if (null != exception) {
            Log.d(TAG, exception.getMessage());
            exception.printStackTrace();
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mSession.startPreview();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mClient.stopStream();
        mSession.stop();
    }

    public void toggleStream() {
        if (!mClient.isStreaming()) {
            String ip,port,path;

            // We save the content user inputs in Shared Preferences
            SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
            SharedPreferences.Editor editor = mPrefs.edit();
            editor.putString("uri", mURI);
            editor.putString("password", mPassword);
            editor.putString("username", mUsername);
            editor.commit();

            // We parse the URI written in the Editext
            Pattern uri = Pattern.compile("rtsp://(.+):(\\d*)/(.+)");
            Matcher m = uri.matcher(mURI); m.find();
            ip = m.group(1);
            port = m.group(2);
            path = m.group(3);

            Log.d(TAG, String.format("Configure client: ip: {0}, port: {1}, path: {2}",
                    ip, port, path));

            mClient.setCredentials(mUsername, mPassword);
            mClient.setServerAddress(ip, Integer.parseInt(port));
            mClient.setStreamPath("/"+path);
            mClient.startStream();

        } else {
            // Stops the stream and disconnects from the RTSP server
            mClient.stopStream();
        }
    }
}

Here is my AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="XXXXX">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.CAMERA" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Here is the error I am getting:

03-17 23:44:25.308 2798-2798/? I/art: Late-enabling -Xcheck:jni
03-17 23:44:25.371 2798-2798/sharedcameralibstreaming W/System: ClassLoader referenced unknown path: /data/app/sharedcameralibstreaming-1/lib/arm
03-17 23:44:25.389 2798-2798/sharedcameralibstreaming D/MainActivity: onCreate()
03-17 23:44:25.392 2798-2798/sharedcameralibstreaming I/MediaStream: Phone supports the MediaCoded API
03-17 23:44:25.392 2798-2798/sharedcameralibstreaming D/AACStream: AAC supported on this phone
03-17 23:44:25.405 2798-2823/sharedcameralibstreaming D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
03-17 23:44:25.436 2798-2823/sharedcameralibstreaming I/Adreno-EGL: <qeglDrvAPI_eglInitialize:379>: QUALCOMM Build: 10/21/15, 369a2ea, I96aee987eb
03-17 23:44:25.439 2798-2823/sharedcameralibstreaming I/OpenGLRenderer: Initialized EGL, version 1.4
03-17 23:44:25.457 2798-2798/sharedcameralibstreaming D/VideoStream: Surface Changed !
03-17 23:44:25.463 2798-2827/sharedcameralibstreaming W/CameraBase: An error occurred while connecting to camera: 0
03-17 23:44:25.491 2798-2798/sharedcameralibstreaming D/MainActivity: onSessionError: reason ERROR_CAMERA_ALREADY_IN_USE
03-17 23:44:25.491 2798-2798/sharedcameralibstreaming D/MainActivity: Fail to connect to camera service
03-17 23:44:25.491 2798-2798/sharedcameralibstreaming W/System.err: net.majorkernelpanic.streaming.exceptions.CameraInUseException: Fail to connect to camera service
03-17 23:44:25.491 2798-2798/sharedcameralibstreaming W/System.err:     at net.majorkernelpanic.streaming.video.VideoStream.openCamera(VideoStream.java:565)
03-17 23:44:25.491 2798-2798/sharedcameralibstreaming W/System.err:     at net.majorkernelpanic.streaming.video.VideoStream.createCamera(VideoStream.java:575)
03-17 23:44:25.492 2798-2798/sharedcameralibstreaming W/System.err:     at net.majorkernelpanic.streaming.video.VideoStream.startPreview(VideoStream.java:314)
03-17 23:44:25.492 2798-2798/sharedcameralibstreaming W/System.err:     at net.majorkernelpanic.streaming.Session$5.run(Session.java:551)
03-17 23:44:25.492 2798-2798/sharedcameralibstreaming W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
03-17 23:44:25.492 2798-2798/sharedcameralibstreaming W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
03-17 23:44:25.492 2798-2798/sharedcameralibstreaming W/System.err:     at android.os.Looper.loop(Looper.java:148)
03-17 23:44:25.492 2798-2798/sharedcameralibstreaming W/System.err:     at android.os.HandlerThread.run(HandlerThread.java:61)

回答1:

I had the same issue, this happens when the first version that you install to the device did not have the permissions for Camera, Audio, etc. These will not be granted automatically by just adding them to your manifest and then redeploying to the phone. The trick is to open the settings, go to the app settings, find your app and then manually enable the permissions for Camera, Audio, etc. From then on, your code should work.