package lilin.com;
|
|
import android.Manifest;
|
import android.app.Activity;
|
import android.content.BroadcastReceiver;
|
import android.content.Context;
|
import android.content.Intent;
|
import android.content.IntentFilter;
|
import android.graphics.Bitmap;
|
import android.graphics.BitmapFactory;
|
import android.graphics.ImageFormat;
|
import android.graphics.Rect;
|
import android.graphics.YuvImage;
|
import android.hardware.Camera;
|
import android.os.Environment;
|
import android.support.annotation.NonNull;
|
import android.support.v7.app.AppCompatActivity;
|
import android.os.Bundle;
|
import android.util.Log;
|
import android.view.Surface;
|
import android.view.SurfaceHolder;
|
import android.view.SurfaceView;
|
import android.view.View;
|
import android.widget.Button;
|
import android.widget.EditText;
|
import android.widget.TextView;
|
import android.widget.Toast;
|
|
import com.github.dfqin.grantor.PermissionListener;
|
import com.github.dfqin.grantor.PermissionsUtil;
|
|
import java.io.ByteArrayOutputStream;
|
import java.io.File;
|
import java.io.FileInputStream;
|
import java.io.FileNotFoundException;
|
import java.io.FileOutputStream;
|
import java.io.IOException;
|
import java.io.OutputStreamWriter;
|
import java.net.InetAddress;
|
import java.util.Arrays;
|
import java.util.List;
|
|
import lilin.com.service.BareSipService;
|
import lilin.com.view.FFWlGLSurfaceView;
|
|
import static android.hardware.Camera.Parameters.PREVIEW_FPS_MAX_INDEX;
|
import static android.hardware.Camera.Parameters.PREVIEW_FPS_MIN_INDEX;
|
import static android.hardware.Camera.Parameters.FLASH_MODE_AUTO;
|
|
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PreviewCallback {
|
|
public static final String RECEIVE_MAIN_ACTIVITY = "receive_main_activity";
|
private EditText id_callnum,id_host,id_user,id_pwd;private TextView id_txt,id_callstate,id_codec; private Button id_reg;
|
private Intent intentOne;
|
private MainActivityReceiver mReceiver;
|
|
private SurfaceView mSurfaceView; private FFWlGLSurfaceView ffsurfaceview;
|
private SurfaceHolder mSurfaceHolder;
|
private String rootp;
|
@Override
|
protected void onCreate(Bundle savedInstanceState) {
|
super.onCreate(savedInstanceState);
|
setContentView(R.layout.activity_main);
|
|
// Example of a call to a native method
|
id_callnum = findViewById(R.id.id_callnum);
|
id_host = findViewById(R.id.id_host);
|
id_user = findViewById(R.id.id_user);
|
id_pwd = findViewById(R.id.id_pwd);
|
id_txt=findViewById(R.id.id_txt);
|
id_callstate=findViewById(R.id.id_callstate);
|
id_codec=findViewById(R.id.id_codec);
|
id_reg=findViewById(R.id.id_reg);
|
ffsurfaceview = this.findViewById(R.id.id_surfaceview);
|
|
|
mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);
|
mSurfaceHolder = mSurfaceView.getHolder();
|
mSurfaceHolder.addCallback(this);
|
|
rootp= Environment.getExternalStorageDirectory().getAbsolutePath();
|
Log.e("roop",""+rootp);
|
|
if (PermissionsUtil.hasPermission(this, new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.READ_PHONE_STATE,Manifest.permission.RECORD_AUDIO,Manifest.permission. CAMERA })) {
|
//有
|
intentOne = new Intent(this, BareSipService.class); startService(intentOne);
|
} else {
|
PermissionsUtil.requestPermission(this, new PermissionListener() {
|
public void permissionGranted(@NonNull String[] permissions) {
|
//用户授予了
|
intentOne = new Intent(MainActivity.this, BareSipService.class); startService(intentOne);
|
}
|
public void permissionDenied(@NonNull String[] permissions) {
|
//用户拒绝了访问摄像头的申请
|
Toast.makeText(MainActivity.this, "权限不足!", Toast.LENGTH_LONG).show();
|
}
|
}, new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.READ_PHONE_STATE,Manifest.permission.RECORD_AUDIO,Manifest.permission. CAMERA });
|
}
|
|
//广播
|
IntentFilter intentFilter = new IntentFilter(RECEIVE_MAIN_ACTIVITY);
|
mReceiver = new MainActivityReceiver();
|
registerReceiver(mReceiver, intentFilter);
|
|
}
|
|
@Override
|
protected void onDestroy() {
|
unregisterReceiver( mReceiver );
|
super.onDestroy();
|
}
|
|
private File file; private String path;
|
public void reg(View view) {
|
String host=id_host.getText().toString(); String pwd=id_pwd.getText().toString(); String user=id_user.getText().toString();
|
if(host.equalsIgnoreCase("")||pwd.equalsIgnoreCase("") ||user.equalsIgnoreCase("")){
|
Toast.makeText(MainActivity.this, "注册信息不全!", Toast.LENGTH_LONG).show();
|
return;
|
}
|
path = getApplicationContext().getFilesDir().getAbsolutePath() + "/accounts";
|
file = new File(path);
|
int exist=file.exists()?1:0;
|
try {
|
FileOutputStream fOut = new FileOutputStream(file.getAbsoluteFile(), false);
|
OutputStreamWriter fWriter = new OutputStreamWriter(fOut);
|
//String res = "<sip:" + user + "@" + host + ";transport=udp>;auth_pass=" + pwd+";medianat=ice;stunserver=stun:lilin:lilinaini@118.190.151.162:3478";
|
String res = "<sip:" + user + "@" + host + ";transport=udp>;auth_pass=" + pwd;
|
try {
|
fWriter.write(res);
|
fWriter.close();
|
fOut.close();
|
|
BareSipService.getInstance().barereg( res );
|
|
} catch (java.io.IOException e) {
|
Log.e("Baresip", "Failed to write accounts file: " + e.toString());
|
}
|
} catch (java.io.FileNotFoundException e) {
|
Log.e("Baresip", "Failed to find accounts file: " + e.toString());
|
}
|
|
|
|
|
}
|
|
public void jie(View view) {
|
BareSipService.getInstance().setDisplay(ffsurfaceview);
|
ffsurfaceview.getWlRender().setVideoType(0);
|
BareSipService.getInstance().barejie();
|
}
|
|
public void gua(View view) {
|
isPublish =false;
|
BareSipService.getInstance().baregua();
|
}
|
|
public void call(View view) {
|
String num =id_callnum.getText().toString();
|
if(num.trim().equals("")){
|
Toast.makeText(MainActivity.this, "num is null!", Toast.LENGTH_LONG).show();
|
return;
|
}
|
BareSipService.getInstance(). barecall("sip:"+num+"@"+id_host.getText().toString()+";transport=udp");
|
}
|
|
public void callv(View view) {
|
String num =id_callnum.getText().toString();
|
if(num.trim().equals("")){
|
Toast.makeText(MainActivity.this, "v num is null!", Toast.LENGTH_LONG).show();
|
return;
|
}
|
BareSipService.getInstance().setDisplay(ffsurfaceview);
|
ffsurfaceview.getWlRender().setVideoType(0);
|
BareSipService.getInstance(). barecallv("sip:"+num+"@"+id_host.getText().toString()+";transport=udp");
|
}
|
|
public void topend(View view) {
|
if(intentOne!=null){
|
stopService(intentOne);
|
}
|
}
|
|
|
|
private Camera mCamera;
|
private Camera.Size size;
|
private boolean isPreview;
|
private boolean isPublish =false;
|
private void openCamera() {
|
try {
|
this.mCamera = Camera.open();
|
} catch (RuntimeException e) {
|
throw new RuntimeException("打开摄像头失败", e);
|
}
|
|
}
|
|
private void setParameters() {
|
Camera.Parameters parameters = mCamera.getParameters();
|
List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
|
for (Camera.Size supportSize : supportedPreviewSizes) {
|
if (supportSize.width >=600 && supportSize.width <= 700) {
|
this.size = supportSize;
|
Log.e("lilin", "setParameters: width:" + size.width + " ,height:" + size.height);
|
break;
|
}
|
}
|
|
int defFPS = 25 * 1000;
|
List<int[]> supportedPreviewFpsRange = parameters.getSupportedPreviewFpsRange();
|
|
int[] destRange = null;
|
for (int i = 0; i < supportedPreviewFpsRange.size(); i++) {
|
int[] range = supportedPreviewFpsRange.get(i);
|
if (range[PREVIEW_FPS_MAX_INDEX] >= defFPS) {
|
destRange = range;
|
Log.e("提示", "setParameters: destRange1:" + Arrays.toString(range));
|
break;
|
}
|
}
|
|
parameters.setPreviewFpsRange(destRange[PREVIEW_FPS_MIN_INDEX], destRange[PREVIEW_FPS_MAX_INDEX]);
|
parameters.setPreviewSize(size.width, size.height);
|
parameters.setFlashMode(FLASH_MODE_AUTO);
|
parameters.setPictureSize(size.width, size.height);
|
parameters.setPreviewFormat(ImageFormat.NV21);
|
mCamera.setParameters(parameters);
|
}
|
public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) {
|
android.hardware.Camera.CameraInfo info =
|
new android.hardware.Camera.CameraInfo();
|
android.hardware.Camera.getCameraInfo(cameraId, info);
|
int rotation = activity.getWindowManager().getDefaultDisplay() .getRotation();
|
int degrees = 0;
|
switch (rotation) {
|
case Surface.ROTATION_0:
|
degrees = 0;
|
break;
|
case Surface.ROTATION_90:
|
degrees = 90;
|
break;
|
case Surface.ROTATION_180:
|
degrees = 180;
|
break;
|
case Surface.ROTATION_270:
|
degrees = 270;
|
break;
|
}
|
|
int result;
|
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
result = (info.orientation + degrees) % 360;
|
result = (360 - result) % 360; // compensate the mirror
|
} else { // back-facing
|
result = (info.orientation - degrees + 360) % 360;
|
}
|
camera.setDisplayOrientation(result);
|
}
|
private void initCamera() {
|
if (this.mCamera == null) {
|
openCamera();
|
}
|
|
setParameters();
|
setCameraDisplayOrientation(this, Camera.CameraInfo.CAMERA_FACING_BACK, mCamera);
|
|
int buffSize = size.width * size.height * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
|
mCamera.addCallbackBuffer(new byte[buffSize]);
|
mCamera.setPreviewCallbackWithBuffer(this);
|
try {
|
mCamera.setPreviewDisplay(mSurfaceHolder);
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
if (isPreview) {
|
mCamera.stopPreview();
|
isPreview = false;
|
}
|
mCamera.startPreview();
|
isPreview = true;
|
}
|
|
@Override
|
public void surfaceCreated(SurfaceHolder holder) {
|
|
}
|
|
@Override
|
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
initCamera();
|
}
|
|
@Override
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
|
}
|
|
|
public static void rotateNV21(byte[] input, byte[] output, int width, int height, int rotation) {
|
boolean swap = (rotation == 90 || rotation == 270);
|
boolean yflip = (rotation == 90 || rotation == 180);
|
boolean xflip = (rotation == 270 || rotation == 180);
|
for (int x = 0; x < width; x++) {
|
for (int y = 0; y < height; y++) {
|
int xo = x, yo = y;
|
int w = width, h = height;
|
int xi = xo, yi = yo;
|
if (swap) {
|
xi = w * yo / h;
|
yi = h * xo / w;
|
}
|
if (yflip) {
|
yi = h - yi - 1;
|
}
|
if (xflip) {
|
xi = w - xi - 1;
|
}
|
output[w * yo + xo] = input[w * yi + xi];
|
int fs = w * h;
|
int qs = (fs >> 2);
|
xi = (xi >> 1);
|
yi = (yi >> 1);
|
xo = (xo >> 1);
|
yo = (yo >> 1);
|
w = (w >> 1);
|
h = (h >> 1);
|
// adjust for interleave here
|
int ui = fs + (w * yi + xi) * 2;
|
int uo = fs + (w * yo + xo) * 2;
|
// and here
|
int vi = ui + 1;
|
int vo = uo + 1;
|
output[uo] = input[ui];
|
output[vo] = input[vi];
|
}
|
}
|
}
|
|
|
@Override
|
public void onPreviewFrame(byte[] data, Camera camera) {
|
/**if (!isPublish) {
|
int w=size.width,h=size.height;
|
YuvImage yuvimage = new YuvImage( data , ImageFormat.NV21, w, h, null);
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
yuvimage.compressToJpeg(new Rect(0, 0, w ,h), 100, baos);// 80--JPG图片的质量[0-100],100最高
|
byte []rawImage = baos.toByteArray();
|
//将rawImage转换成bitmap
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
options.inPreferredConfig = Bitmap.Config.RGB_565;
|
Bitmap bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length, options);
|
FileOutputStream fos = null;
|
try {
|
fos = new FileOutputStream(new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/DCIM/Camera/1.jpg"));
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
|
fos.flush();
|
fos.close();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}**/
|
if (isPublish) {
|
//Pusher.push(data,size.width,size.height);
|
byte[] outdata = new byte[data.length];
|
rotateNV21(data,outdata,size.width,size.height ,90);
|
BareSipService.getInstance().bareSendv(outdata ,size.width,size.height );
|
}
|
|
int buffSize = size.width * size.height * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
|
|
if (data == null) {
|
mCamera.addCallbackBuffer(new byte[buffSize]);
|
} else {
|
mCamera.addCallbackBuffer(data);
|
}
|
}
|
|
|
public class MainActivityReceiver extends BroadcastReceiver {
|
@Override
|
public void onReceive(Context context, Intent intent) {
|
String action = intent.getStringExtra("action");
|
switch (action) {
|
case "reg_state":
|
int state=intent.getIntExtra("data",0);
|
if(state==0){
|
id_txt.setText("注册失败!");
|
}else{
|
id_txt.setText("注册ok!");
|
}
|
break;
|
case "vstart":
|
isPublish = true;
|
break;
|
case "vstop":
|
isPublish = false;Log.e("提示","结束了哦");
|
break;
|
case "callstate":
|
id_callstate.setText(intent.getStringExtra("data"));
|
break;
|
case "codec":
|
id_codec.setText(intent.getStringExtra("data"));
|
break;
|
}
|
}
|
}
|
|
}
|