我正在尝试使用libstream库来流式传输我的手机摄像头输出。我基于示例 3 构建了我的应用程序。但是,当我使用Nexus 5(使用Android 6.0.1)进行USB调试时,我只是不断收到这个ERROR_CAMERA_ALREADY_IN_USE异常。我尝试杀死其他应用程序,重新启动手机,但例外仍然存在。我在网上检查并看到了这个,但它没有给我正确的答案。所以我正在尝试寻求帮助,我很感激任何回复。这是我的主要活动:
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();
}
}
}
这是我的安卓清单.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>
这是我得到的错误:
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)
我遇到了同样的问题,当您安装到设备的第一个版本没有相机、音频等权限时,就会发生这种情况。仅将它们添加到清单,然后重新部署到手机,不会自动授予这些权限。诀窍是打开设置,转到应用程序设置,找到您的应用程序,然后手动启用相机,音频等的权限。从那时起,您的代码应该可以工作。