|
|
@ -3,12 +3,14 @@ package org.easydarwin.push;
|
|
|
|
import android.app.Activity;
|
|
|
|
import android.app.Activity;
|
|
|
|
import android.app.Application;
|
|
|
|
import android.app.Application;
|
|
|
|
import android.app.Service;
|
|
|
|
import android.app.Service;
|
|
|
|
|
|
|
|
|
|
|
|
import androidx.lifecycle.Lifecycle;
|
|
|
|
import androidx.lifecycle.Lifecycle;
|
|
|
|
import androidx.lifecycle.LifecycleObserver;
|
|
|
|
import androidx.lifecycle.LifecycleObserver;
|
|
|
|
import androidx.lifecycle.LifecycleOwner;
|
|
|
|
import androidx.lifecycle.LifecycleOwner;
|
|
|
|
import androidx.lifecycle.LiveData;
|
|
|
|
import androidx.lifecycle.LiveData;
|
|
|
|
import androidx.lifecycle.Observer;
|
|
|
|
import androidx.lifecycle.Observer;
|
|
|
|
import androidx.lifecycle.OnLifecycleEvent;
|
|
|
|
import androidx.lifecycle.OnLifecycleEvent;
|
|
|
|
|
|
|
|
|
|
|
|
import android.content.ComponentName;
|
|
|
|
import android.content.ComponentName;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.content.Intent;
|
|
|
@ -30,9 +32,11 @@ import android.os.HandlerThread;
|
|
|
|
import android.os.IBinder;
|
|
|
|
import android.os.IBinder;
|
|
|
|
import android.os.Process;
|
|
|
|
import android.os.Process;
|
|
|
|
import android.preference.PreferenceManager;
|
|
|
|
import android.preference.PreferenceManager;
|
|
|
|
|
|
|
|
|
|
|
|
import androidx.annotation.MainThread;
|
|
|
|
import androidx.annotation.MainThread;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
import androidx.core.app.ActivityCompat;
|
|
|
|
import androidx.core.app.ActivityCompat;
|
|
|
|
|
|
|
|
|
|
|
|
import android.text.TextUtils;
|
|
|
|
import android.text.TextUtils;
|
|
|
|
import android.util.Log;
|
|
|
|
import android.util.Log;
|
|
|
|
import android.view.Surface;
|
|
|
|
import android.view.Surface;
|
|
|
@ -90,12 +94,12 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class MediaBinder extends Binder {
|
|
|
|
public class MediaBinder extends Binder {
|
|
|
|
public MediaStream getService(){
|
|
|
|
public MediaStream getService() {
|
|
|
|
return MediaStream.this;
|
|
|
|
return MediaStream.this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static class MediaStreamPublisher implements Publisher<MediaStream>, LifecycleObserver{
|
|
|
|
static class MediaStreamPublisher implements Publisher<MediaStream>, LifecycleObserver {
|
|
|
|
|
|
|
|
|
|
|
|
private final LifecycleOwner lifecyclerOwner;
|
|
|
|
private final LifecycleOwner lifecyclerOwner;
|
|
|
|
private ServiceConnection conn;
|
|
|
|
private ServiceConnection conn;
|
|
|
@ -129,21 +133,21 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
Context c = context.get();
|
|
|
|
Context c = context.get();
|
|
|
|
if (c == null) return;
|
|
|
|
if (c == null) return;
|
|
|
|
Intent serv = new Intent(c, MediaStream.class);
|
|
|
|
Intent serv = new Intent(c, MediaStream.class);
|
|
|
|
if (!c.bindService(serv, conn, 0)){
|
|
|
|
if (!c.bindService(serv, conn, 0)) {
|
|
|
|
s.onError(new IllegalStateException("bindService error!"));
|
|
|
|
s.onError(new IllegalStateException("bindService error!"));
|
|
|
|
s.onComplete();
|
|
|
|
s.onComplete();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@OnLifecycleEvent(value = Lifecycle.Event.ON_DESTROY)
|
|
|
|
@OnLifecycleEvent(value = Lifecycle.Event.ON_DESTROY)
|
|
|
|
void destory(){
|
|
|
|
void destory() {
|
|
|
|
Context c = context.get();
|
|
|
|
Context c = context.get();
|
|
|
|
if (c == null) return;
|
|
|
|
if (c == null) return;
|
|
|
|
c.unbindService(conn);
|
|
|
|
c.unbindService(conn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static Publisher<MediaStream> getBindedMediaStream(final Context context, LifecycleOwner owner){
|
|
|
|
public static Publisher<MediaStream> getBindedMediaStream(final Context context, LifecycleOwner owner) {
|
|
|
|
final MediaStreamPublisher publisher = new MediaStreamPublisher(context, owner);
|
|
|
|
final MediaStreamPublisher publisher = new MediaStreamPublisher(context, owner);
|
|
|
|
return publisher;
|
|
|
|
return publisher;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -186,13 +190,14 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
boolean hevcEncode = false;
|
|
|
|
boolean hevcEncode = false;
|
|
|
|
public String mime = "";
|
|
|
|
public String mime = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public CodecInfo info = new CodecInfo();
|
|
|
|
public CodecInfo info = new CodecInfo();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void startStream(String ip, String port, String id, InitCallback callback) {
|
|
|
|
public void startStream(String ip, String port, String id, InitCallback callback) {
|
|
|
|
mEasyPusher.initPush( mApplicationContext, callback);
|
|
|
|
mEasyPusher.initPush(mApplicationContext, callback);
|
|
|
|
PushingState.sCodec = mSWCodec ? "x264":(info.hevcEncode ? "hevc":"avc");
|
|
|
|
PushingState.sCodec = mSWCodec ? "x264" : (info.hevcEncode ? "hevc" : "avc");
|
|
|
|
mEasyPusher.setMediaInfo(!mSWCodec && info.hevcEncode ? Pusher.Codec.EASY_SDK_VIDEO_CODEC_H265:Pusher.Codec.EASY_SDK_VIDEO_CODEC_H264, 25, Pusher.Codec.EASY_SDK_AUDIO_CODEC_AAC, 1, 8000, 16);
|
|
|
|
mEasyPusher.setMediaInfo(!mSWCodec && info.hevcEncode ? Pusher.Codec.EASY_SDK_VIDEO_CODEC_H265 : Pusher.Codec.EASY_SDK_VIDEO_CODEC_H264, 25, Pusher.Codec.EASY_SDK_AUDIO_CODEC_AAC, 1, 8000, 16);
|
|
|
|
mEasyPusher.start(ip, port, String.format("%s.sdp", id), Pusher.TransType.EASY_RTP_OVER_TCP);
|
|
|
|
mEasyPusher.start(ip, port, String.format("%s.sdp", id), Pusher.TransType.EASY_RTP_OVER_TCP);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -212,7 +217,7 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
if (pushScreenService != null) {
|
|
|
|
if (pushScreenService != null) {
|
|
|
|
stopPushScreen();
|
|
|
|
stopPushScreen();
|
|
|
|
|
|
|
|
|
|
|
|
}else{
|
|
|
|
} else {
|
|
|
|
Intent intent = new Intent(mApplicationContext, PushScreenService.class);
|
|
|
|
Intent intent = new Intent(mApplicationContext, PushScreenService.class);
|
|
|
|
|
|
|
|
|
|
|
|
conn = new ServiceConnection() {
|
|
|
|
conn = new ServiceConnection() {
|
|
|
@ -252,7 +257,7 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
public final String msg;
|
|
|
|
public final String msg;
|
|
|
|
public final String url;
|
|
|
|
public final String url;
|
|
|
|
public final boolean screenPushing;
|
|
|
|
public final boolean screenPushing;
|
|
|
|
static String sCodec ="avc";
|
|
|
|
static String sCodec = "avc";
|
|
|
|
public String videoCodec = sCodec;
|
|
|
|
public String videoCodec = sCodec;
|
|
|
|
|
|
|
|
|
|
|
|
public PushingState(int state, String msg) {
|
|
|
|
public PushingState(int state, String msg) {
|
|
|
@ -351,7 +356,7 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
|
|
|
|
|
|
|
|
mApplicationContext = getApplication();
|
|
|
|
mApplicationContext = getApplication();
|
|
|
|
File youyuan = getFileStreamPath("SIMYOU.ttf");
|
|
|
|
File youyuan = getFileStreamPath("SIMYOU.ttf");
|
|
|
|
if (!youyuan.exists()){
|
|
|
|
if (!youyuan.exists()) {
|
|
|
|
AssetManager am = getAssets();
|
|
|
|
AssetManager am = getAssets();
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
InputStream is = am.open("zk/SIMYOU.ttf");
|
|
|
|
InputStream is = am.open("zk/SIMYOU.ttf");
|
|
|
@ -403,32 +408,30 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void onPreviewFrame2(byte[] data, Object camera) {
|
|
|
|
public void onPreviewFrame2(byte[] data, Object camera) {
|
|
|
|
|
|
|
|
boolean enableOverlay = PreferenceManager.getDefaultSharedPreferences(mApplicationContext).getBoolean("key_enable_video_overlay", true);
|
|
|
|
if (camera instanceof Camera) {
|
|
|
|
if (camera instanceof Camera) {
|
|
|
|
if (PreferenceManager.getDefaultSharedPreferences(mApplicationContext).getBoolean("key_enable_video_overlay", true)) {
|
|
|
|
|
|
|
|
overlay.javaOverlay(data, "EasyPusher");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mDgree == 0) {
|
|
|
|
|
|
|
|
Camera.CameraInfo camInfo = new Camera.CameraInfo();
|
|
|
|
Camera.CameraInfo camInfo = new Camera.CameraInfo();
|
|
|
|
Camera.getCameraInfo(mCameraId, camInfo);
|
|
|
|
Camera.getCameraInfo(mCameraId, camInfo);
|
|
|
|
int cameraRotationOffset = camInfo.orientation;
|
|
|
|
int cameraRotationOffset = camInfo.orientation;
|
|
|
|
|
|
|
|
if (enableOverlay) {
|
|
|
|
|
|
|
|
overlay.javaOverlay(data, width, height, cameraRotationOffset, "EasyPusher");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mDgree == 0) {
|
|
|
|
if (cameraRotationOffset % 180 != 0) {
|
|
|
|
if (cameraRotationOffset % 180 != 0) {
|
|
|
|
yuvRotate(data, 1, width, height, cameraRotationOffset);
|
|
|
|
yuvRotate(data, 1, width, height, cameraRotationOffset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
save2file(data, String.format("/sdcard/yuv_%d_%d.yuv", height, width));
|
|
|
|
save2file(data, String.format("/sdcard/yuv_%d_%d.yuv", height, width));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (PreferenceManager.getDefaultSharedPreferences(mApplicationContext).getBoolean("key_enable_video_overlay", true)) {
|
|
|
|
if (enableOverlay) {
|
|
|
|
String txt;// = String.format("drawtext=fontfile=" + mApplicationContext.getFileStreamPath("SIMYOU.ttf") + ": text='%s%s':x=(w-text_w)/2:y=H-60 :fontcolor=white :box=1:boxcolor=0x00000000@0.3", "EasyPusher", new SimpleDateFormat("yyyy-MM-ddHHmmss").format(new Date()));
|
|
|
|
String txt = "EasyPusher " + new SimpleDateFormat("yy-MM-dd HH:mm:ss SSS").format(new Date());
|
|
|
|
txt = "EasyPusher " + new SimpleDateFormat("yy-MM-dd HH:mm:ss SSS").format(new Date());
|
|
|
|
|
|
|
|
overlay.overlay(data, txt);
|
|
|
|
overlay.overlay(data, txt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mVC.onVideo(data, NV21);
|
|
|
|
mVC.onVideo(data, NV21);
|
|
|
|
mCamera.addCallbackBuffer(data);
|
|
|
|
mCamera.addCallbackBuffer(data);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (PreferenceManager.getDefaultSharedPreferences(mApplicationContext).getBoolean("key_enable_video_overlay", true)) {
|
|
|
|
if (enableOverlay) {
|
|
|
|
String txt;// = String.format("drawtext=fontfile=" + mApplicationContext.getFileStreamPath("SIMYOU.ttf") + ": text='%s%s':x=(w-text_w)/2:y=H-60 :fontcolor=white :box=1:boxcolor=0x00000000@0.3", "EasyPusher", new SimpleDateFormat("yyyy-MM-ddHHmmss").format(new Date()));
|
|
|
|
String txt = "EasyPusher " + new SimpleDateFormat("yy-MM-dd HH:mm:ss SSS").format(new Date());
|
|
|
|
txt = "EasyPusher " + new SimpleDateFormat("yy-MM-dd HH:mm:ss SSS").format(new Date());
|
|
|
|
overlay.javaOverlay(data, width, height, 0, txt);
|
|
|
|
overlay.javaOverlay(data, txt);
|
|
|
|
|
|
|
|
overlay.overlay(data, txt);
|
|
|
|
overlay.overlay(data, txt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mVC.onVideo(data, NV21);
|
|
|
|
mVC.onVideo(data, NV21);
|
|
|
@ -442,7 +445,7 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
mCameraHandler.post(new Runnable() {
|
|
|
|
mCameraHandler.post(new Runnable() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
public void run() {
|
|
|
|
startStream(ip,port, id);
|
|
|
|
startStream(ip, port, id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@ -454,7 +457,7 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void onCallback(int code) {
|
|
|
|
public void onCallback(int code) {
|
|
|
|
String msg = "";
|
|
|
|
String msg = "";
|
|
|
|
String url = String.format("rtsp://%s:%s/%s.sdp", ip,port,id);
|
|
|
|
String url = String.format("rtsp://%s:%s/%s.sdp", ip, port, id);
|
|
|
|
switch (code) {
|
|
|
|
switch (code) {
|
|
|
|
case EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_INVALID_KEY:
|
|
|
|
case EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_INVALID_KEY:
|
|
|
|
msg = ("无效Key");
|
|
|
|
msg = ("无效Key");
|
|
|
@ -495,7 +498,7 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// mEasyPusher.initPush(ip, port, String.format("%s.sdp", id), mApplicationContext, callback);
|
|
|
|
// mEasyPusher.initPush(ip, port, String.format("%s.sdp", id), mApplicationContext, callback);
|
|
|
|
startStream(ip,port,id, callback);
|
|
|
|
startStream(ip, port, id, callback);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -515,12 +518,12 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public boolean isScreenPushing(){
|
|
|
|
public boolean isScreenPushing() {
|
|
|
|
return pushScreenService != null;
|
|
|
|
return pushScreenService != null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public boolean isCameraPushing(){
|
|
|
|
public boolean isCameraPushing() {
|
|
|
|
return cameraPushing;
|
|
|
|
return cameraPushing;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -592,15 +595,15 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void initEncoder(Context context, CodecInfo info){
|
|
|
|
public static void initEncoder(Context context, CodecInfo info) {
|
|
|
|
info.hevcEncode = false;
|
|
|
|
info.hevcEncode = false;
|
|
|
|
boolean try265Encode = PreferenceManager.getDefaultSharedPreferences(context).getBoolean("try_265_encode", false);
|
|
|
|
boolean try265Encode = PreferenceManager.getDefaultSharedPreferences(context).getBoolean("try_265_encode", false);
|
|
|
|
ArrayList<CodecInfo> infos = listEncoders(try265Encode ?MediaFormat.MIMETYPE_VIDEO_HEVC:MediaFormat.MIMETYPE_VIDEO_AVC);
|
|
|
|
ArrayList<CodecInfo> infos = listEncoders(try265Encode ? MediaFormat.MIMETYPE_VIDEO_HEVC : MediaFormat.MIMETYPE_VIDEO_AVC);
|
|
|
|
if (infos.isEmpty()) {
|
|
|
|
if (infos.isEmpty()) {
|
|
|
|
if (try265Encode){
|
|
|
|
if (try265Encode) {
|
|
|
|
infos = listEncoders(MediaFormat.MIMETYPE_VIDEO_AVC);
|
|
|
|
infos = listEncoders(MediaFormat.MIMETYPE_VIDEO_AVC);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
} else {
|
|
|
|
if (try265Encode) info.hevcEncode = true;
|
|
|
|
if (try265Encode) info.hevcEncode = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!infos.isEmpty()) {
|
|
|
|
if (!infos.isEmpty()) {
|
|
|
@ -608,7 +611,7 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
info.mName = ci.mName;
|
|
|
|
info.mName = ci.mName;
|
|
|
|
info.mColorFormat = ci.mColorFormat;
|
|
|
|
info.mColorFormat = ci.mColorFormat;
|
|
|
|
info.mime = ci.mime;
|
|
|
|
info.mime = ci.mime;
|
|
|
|
}else{
|
|
|
|
} else {
|
|
|
|
info.mName = "";
|
|
|
|
info.mName = "";
|
|
|
|
info.mColorFormat = 0;
|
|
|
|
info.mColorFormat = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -643,10 +646,10 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
if (value != null) {
|
|
|
|
if (value != null) {
|
|
|
|
// uvc camera.
|
|
|
|
// uvc camera.
|
|
|
|
uvcCamera = value;
|
|
|
|
uvcCamera = value;
|
|
|
|
value.setPreviewSize(width, height,1, 30, UVCCamera.PIXEL_FORMAT_YUV420SP,1.0f);
|
|
|
|
value.setPreviewSize(width, height, 1, 30, UVCCamera.PIXEL_FORMAT_YUV420SP, 1.0f);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
// value.startPreview();
|
|
|
|
// value.startPreview();
|
|
|
|
}else{
|
|
|
|
} else {
|
|
|
|
Log.i(TAG, "NO UVCCamera");
|
|
|
|
Log.i(TAG, "NO UVCCamera");
|
|
|
|
uvcError = new Exception("no uvccamera connected!");
|
|
|
|
uvcError = new Exception("no uvccamera connected!");
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@ -752,7 +755,7 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
return length;
|
|
|
|
return length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public synchronized boolean isRecording(){
|
|
|
|
public synchronized boolean isRecording() {
|
|
|
|
return mIsRecording;
|
|
|
|
return mIsRecording;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -828,11 +831,11 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
value.setFrameCallback(uvcFrameCallback, UVCCamera.PIXEL_FORMAT_YUV420SP/*UVCCamera.PIXEL_FORMAT_NV21*/);
|
|
|
|
value.setFrameCallback(uvcFrameCallback, UVCCamera.PIXEL_FORMAT_YUV420SP/*UVCCamera.PIXEL_FORMAT_NV21*/);
|
|
|
|
value.startPreview();
|
|
|
|
value.startPreview();
|
|
|
|
cameraPreviewResolution.postValue(new int[]{width, height});
|
|
|
|
cameraPreviewResolution.postValue(new int[]{width, height});
|
|
|
|
}catch (Throwable e){
|
|
|
|
} catch (Throwable e) {
|
|
|
|
uvcError = e;
|
|
|
|
uvcError = e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}else if (mCamera != null) {
|
|
|
|
} else if (mCamera != null) {
|
|
|
|
int previewFormat = mCamera.getParameters().getPreviewFormat();
|
|
|
|
int previewFormat = mCamera.getParameters().getPreviewFormat();
|
|
|
|
Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
|
|
|
|
Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
|
|
|
|
int size = previewSize.width * previewSize.height * ImageFormat.getBitsPerPixel(previewFormat) / 8;
|
|
|
|
int size = previewSize.width * previewSize.height * ImageFormat.getBitsPerPixel(previewFormat) / 8;
|
|
|
@ -989,7 +992,6 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param cameraId 0表示后置,1表示前置,2表示uvc摄像头,-1表示默认切换(比如前后置来回切换.).在非-1的情况下,如果没有ID对应的摄像头,则也会作默认切换.
|
|
|
|
* @param cameraId 0表示后置,1表示前置,2表示uvc摄像头,-1表示默认切换(比如前后置来回切换.).在非-1的情况下,如果没有ID对应的摄像头,则也会作默认切换.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public Publisher<Object> switchCamera(final int cameraId) {
|
|
|
|
public Publisher<Object> switchCamera(final int cameraId) {
|
|
|
@ -1005,7 +1007,7 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
return pub;
|
|
|
|
return pub;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void switchCamera(){
|
|
|
|
public void switchCamera() {
|
|
|
|
switchCamera(-1).subscribe(new Subscriber<Object>() {
|
|
|
|
switchCamera(-1).subscribe(new Subscriber<Object>() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void onSubscribe(Subscription s) {
|
|
|
|
public void onSubscribe(Subscription s) {
|
|
|
@ -1062,23 +1064,23 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
destroyCamera();
|
|
|
|
destroyCamera();
|
|
|
|
createCamera();
|
|
|
|
createCamera();
|
|
|
|
startPreview();
|
|
|
|
startPreview();
|
|
|
|
}finally {
|
|
|
|
} finally {
|
|
|
|
if (uvcCamera != null){
|
|
|
|
if (uvcCamera != null) {
|
|
|
|
if (mSwitchCameraSubscriber != null){
|
|
|
|
if (mSwitchCameraSubscriber != null) {
|
|
|
|
mSwitchCameraSubscriber.onNext(uvcCamera);
|
|
|
|
mSwitchCameraSubscriber.onNext(uvcCamera);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}else if (mCamera != null){
|
|
|
|
} else if (mCamera != null) {
|
|
|
|
if (mSwitchCameraSubscriber != null){
|
|
|
|
if (mSwitchCameraSubscriber != null) {
|
|
|
|
mSwitchCameraSubscriber.onNext(mCamera);
|
|
|
|
mSwitchCameraSubscriber.onNext(mCamera);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}else {
|
|
|
|
} else {
|
|
|
|
if (mSwitchCameraSubscriber != null){
|
|
|
|
if (mSwitchCameraSubscriber != null) {
|
|
|
|
if (uvcError != null){
|
|
|
|
if (uvcError != null) {
|
|
|
|
mSwitchCameraSubscriber.onError(uvcError);
|
|
|
|
mSwitchCameraSubscriber.onError(uvcError);
|
|
|
|
}else {
|
|
|
|
} else {
|
|
|
|
mSwitchCameraSubscriber.onError(new IOException("could not create camera of id:" + mCameraId));
|
|
|
|
mSwitchCameraSubscriber.onError(new IOException("could not create camera of id:" + mCameraId));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
} else {
|
|
|
|
// uvcCamera = new UVCCamera();
|
|
|
|
// uvcCamera = new UVCCamera();
|
|
|
|
// mSwitchCameraSubscriber.onNext(uvcCamera);
|
|
|
|
// mSwitchCameraSubscriber.onNext(uvcCamera);
|
|
|
|
// if (uvcFrameCallback != null){
|
|
|
|
// if (uvcFrameCallback != null){
|
|
|
@ -1173,9 +1175,9 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
mCameraHandler.post(new Runnable() {
|
|
|
|
mCameraHandler.post(new Runnable() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
public void run() {
|
|
|
|
if (uvcCamera != null){
|
|
|
|
if (uvcCamera != null) {
|
|
|
|
uvcCamera.setPreviewDisplay((Surface) null);
|
|
|
|
uvcCamera.setPreviewDisplay((Surface) null);
|
|
|
|
}else {
|
|
|
|
} else {
|
|
|
|
stopPreview();
|
|
|
|
stopPreview();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1187,9 +1189,9 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
mCameraHandler.post(new Runnable() {
|
|
|
|
mCameraHandler.post(new Runnable() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
public void run() {
|
|
|
|
if (uvcCamera != null){
|
|
|
|
if (uvcCamera != null) {
|
|
|
|
uvcCamera.setPreviewDisplay(new Surface(texture));
|
|
|
|
uvcCamera.setPreviewDisplay(new Surface(texture));
|
|
|
|
}else {
|
|
|
|
} else {
|
|
|
|
stopPreview();
|
|
|
|
stopPreview();
|
|
|
|
if (cameraOpened) openCameraPreview();
|
|
|
|
if (cameraOpened) openCameraPreview();
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1245,7 +1247,6 @@ public class MediaStream extends Service implements LifecycleObserver {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static ArrayList<CodecInfo> listEncoders(String mime) {
|
|
|
|
public static ArrayList<CodecInfo> listEncoders(String mime) {
|
|
|
|
// 可能有多个编码库,都获取一下。。。
|
|
|
|
// 可能有多个编码库,都获取一下。。。
|
|
|
|
ArrayList<CodecInfo> codecInfos = new ArrayList<CodecInfo>();
|
|
|
|
ArrayList<CodecInfo> codecInfos = new ArrayList<CodecInfo>();
|
|
|
|