1 package ai.suanzi.rtmpclient;
3 import android.app.Activity;
4 import android.app.PendingIntent;
5 import android.content.BroadcastReceiver;
6 import android.content.IntentFilter;
7 import android.graphics.ImageFormat;
8 import android.graphics.SurfaceTexture;
9 import android.hardware.usb.UsbDevice;
10 import android.hardware.usb.UsbManager;
11 import android.os.Environment;
12 import android.support.design.widget.TextInputEditText;
13 import android.support.v7.app.AppCompatActivity;
14 import android.os.Bundle;
15 import android.text.TextUtils;
16 import android.util.Log;
17 import android.view.SurfaceHolder;
18 import android.hardware.Camera;
19 import android.view.SurfaceView;
20 import android.view.View;
21 import android.widget.Button;
22 import android.widget.Toast;
23 import android.content.Context;
24 import android.content.pm.PackageManager;
25 import android.os.AsyncTask;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.io.IOException;
32 import java.util.concurrent.Executor;
33 import java.util.concurrent.ExecutorService;
34 import java.util.concurrent.Executors;
35 import android.content.Intent;
36 import java.io.OutputStream;
37 import android.hardware.usb.UsbManager;
38 import android.hardware.usb.UsbDeviceConnection;
40 import de.mindpipe.android.logging.log4j.LogConfigurator;
41 import org.apache.log4j.Level;
42 import org.apache.log4j.Logger;
43 import android.net.wifi.WifiManager;
44 import android.net.wifi.WifiInfo;
46 //"rtmp://gpussh.suanzi.ai:1935/myapp/suanzi_ac83f34ead90_cameraid";
48 public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PreviewCallback{
50 private static final String TAG = "PENG";
51 private Ffmpeg ffmpeg;
52 private Camera mCamera ;
53 private StreamTask mStreamTask;
54 private SurfaceHolder mHolder;
55 private SurfaceView mSufaceView;
56 private UVCCamera uvcCamera;
57 ExecutorService mExecutor = Executors.newSingleThreadExecutor();
58 //Intent it = new Intent(getApplicationContext(), MyService.class);
59 Intent intent = new Intent();
61 private UsbManager usbManager;
62 private UsbDevice usbCamera;
64 private Logger gLogger;
66 private Button mBtnStart;
67 private TextInputEditText mTextServer;
68 private TextInputEditText mTextUser;
69 private TextInputEditText mTextCamera;
70 private String mMacAddr = "";
72 private void configLog(){
74 final LogConfigurator logConfigurator = new LogConfigurator();
75 String fname = getExternalFilesDir(null) + File.separator + "log.txt";
76 logConfigurator.setFileName(fname);
77 Log.e(TAG, "Log file is located at: " + fname);
78 logConfigurator.setRootLevel(Level.DEBUG);
79 logConfigurator.setLevel("org.apache", Level.ERROR);
80 logConfigurator.setMaxFileSize(1024 * 1024 * 10);
81 logConfigurator.configure();
82 gLogger = Logger.getLogger(getClass());
83 } catch (Exception e){
90 gLogger.debug("#######################################");
91 UserInfo.setConfigPath(getExternalFilesDir(null) + File.separator + "config");
92 this.mMacAddr = getMacAddr();
94 ffmpeg = Ffmpeg.getInstance();
95 uvcCamera = new UVCCamera();
97 mBtnStart = findViewById(R.id.button);
98 mTextServer = findViewById(R.id.textServer);
99 mTextUser = findViewById(R.id.textUser);
100 mTextCamera = findViewById(R.id.textCamera);
104 intent.setPackage(this.getPackageName());
105 intent.setAction("ai.suanzi.rtmpclient.service");
108 mSufaceView = findViewById(R.id.surfaceView);
109 mHolder = mSufaceView.getHolder();
110 mHolder.addCallback(this);
113 mCamera = getCameraInstance();
114 configCamera(mCamera);
119 protected void onCreate(Bundle savedInstanceState) {
120 super.onCreate(savedInstanceState);
121 setContentView(R.layout.activity_main);
124 mBtnStart.setOnClickListener(new View.OnClickListener(){
126 public void onClick(View view){
127 String url = mTextServer.getText().toString() + "/" + mTextUser.getText().toString() + "_" + mMacAddr + "_" + mTextCamera.getText().toString();
128 gLogger.error("----------> onClick, Url is: " + url);
129 intent.putExtra("url", url);
130 startService(intent);
132 //changePermission();
136 /*btn2.post(new Runnable(){
144 switchToBackground();*/
147 usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
148 HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
149 Log.e(TAG, "device list size : " + deviceList.size());
150 Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
151 PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
153 IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED);
154 registerReceiver(mUsbReceiver, filter);
155 filter = new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED);
156 registerReceiver(mUsbReceiver, filter);
157 filter = new IntentFilter(ACTION_USB_PERMISSION);
158 registerReceiver(mUsbReceiver, filter);
160 while(deviceIterator.hasNext()){
161 UsbDevice device = deviceIterator.next();
162 Log.e(TAG, device.toString());
163 Log.e(TAG, device.getDeviceName() + " manufacture name: " + device.getManufacturerName() + " " + device.getSerialNumber() + " " + device.getDeviceId());
165 if (device.getVendorId() == 6257){
166 usbManager.requestPermission(device, mPermissionIntent);
167 Log.e(TAG,"XXXXXXXXXXXXXXXXXXXXXXXXXXX");
168 Log.e(TAG, device.getVendorId() + "\n" + device.getProductId() + "\n" + device.getProductName() + "\n" +
169 device.getManufacturerName() + "\n" + device.getDeviceId() + "\n" + device.getSerialNumber() + "\n" +
170 device.getDeviceName());
172 final String name = device.getDeviceName();
173 final String[] v = name.split("/");
177 busnum = Integer.parseInt(v[v.length-2]);
178 devnum = Integer.parseInt(v[v.length-1]);
182 uData.vid = device.getVendorId();
183 uData.pid = device.getProductId();
184 uData.busNum = busnum;
185 uData.devNum = devnum;
187 String result = null;
188 final String[] vv = name.split("/");
189 if ((vv != null) && (vv.length > 2)) {
190 final StringBuilder sb = new StringBuilder(vv[0]);
191 for (int i = 1; i < vv.length - 2; i++)
192 sb.append("/").append(vv[i]);
193 result = sb.toString();
195 uData.usbFsName = result;
203 //Log.e(TAG, device.)
204 //device.getInterface()
208 /*private UsbData uData = new UsbData();
210 private class UsbData {
216 public String usbFsName;
218 Log.e(TAG, "vid=" + vid + ". pid=" + pid + ". fd=" + fd + ". busnum=" + busNum + ". devNum=" + devNum + ". usbFsName=" + usbFsName);
222 //SurfaceTexture st = new SurfaceTexture(0);
224 /*private static final String ACTION_USB_PERMISSION =
225 "com.android.example.USB_PERMISSION";
226 private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
228 public void onReceive(Context context, Intent intent) {
229 String action = intent.getAction();
230 if (ACTION_USB_PERMISSION.equals(action)) {
231 synchronized (this) {
232 UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
234 if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true)) {
236 Log.e(TAG, "extra permission granted");
237 //call method to set up device communication
240 new Thread(new Runnable() {
243 Log.e("device","MyThread3");//bhw
244 UsbDeviceConnection connection = usbManager.openDevice(usbCamera);
245 int fd = connection.getFileDescriptor();//获取文件描述符
248 int ret = uvcCamera.open(uData.vid, uData.pid, uData.fd, uData.busNum, uData.devNum, uData.usbFsName);
249 Log.e(TAG, "uvcCamera open return code:" + ret);
251 Log.e("device","MyThread3 "+fd);
258 Log.e(TAG, "permission denied for device. " + device);
261 } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)){
262 UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
264 Log.e(TAG, "==== device out");
266 } else if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
267 Log.e(TAG, "==== device in =====");
276 protected void onPause(){
278 gLogger.debug("OnPause");
282 protected void onResume() {
284 gLogger.debug("OnResume");
288 protected void onStop() {
290 gLogger.debug("onStop");
294 protected void onStart(){
296 gLogger.debug("onStart");
300 protected void onDestroy(){
302 gLogger.debug("onDestroy");
306 protected void onRestart(){
308 gLogger.debug("onRestart");
312 // class StreamTask AsyncTask
313 private class StreamTask extends AsyncTask<Void, Void, Void>{
316 StreamTask(byte[] data){
321 protected Void doInBackground(Void... params) {
323 if (this.data != null){
324 Log.e(TAG, "fps: " + mCamera.getParameters().getPreviewFrameRate());
325 ffmpeg.process(this.data);
334 // SurfaceHolder.Callback implementation
336 public void surfaceCreated(final SurfaceHolder holder){
337 gLogger.error("SurfacedCreated");
341 public void surfaceChanged(SurfaceHolder holder, int format, int widht, int height){
342 gLogger.error("surfaceChanged");
344 mCamera.setPreviewDisplay(holder);
345 mCamera.startPreview();
346 } catch (Exception e){
347 gLogger.error("Error starting camera previewe: " + e.getMessage());
348 Toast.makeText(this, "Camera Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
353 public void surfaceDestroyed(SurfaceHolder holder){
354 Log.e(TAG, "surfaceDestroyed");
358 public void onPreviewFrame(final byte[] data, Camera camera){
359 gLogger.error("onPreviewFrame");
360 if (null != mStreamTask){
361 switch (mStreamTask.getStatus()){
363 Log.e(TAG, "onPreviewFrame Running");
366 Log.e(TAG,"OnPreviewFrame Pending");
367 mStreamTask.cancel(false);
371 mStreamTask = new StreamTask(data);
372 mStreamTask.execute((Void)null);
375 // ong endTime = System.currentTimeMillis();
376 // mExecutor.execute(new Runnable() {
378 // public void run() {
379 // //long encodeTime = System.currentTimeMillis();
380 // ffmpeg.process(data);
381 //Log.e(TAG, "编码第:" + (encodeCount++) + "帧,耗时:" + (System.currentTimeMillis() - encodeTime));
384 //Log.e(TAG, "采集第:" + (++count) + "帧,距上一帧间隔时间:"
385 // + (endTime - previewTime) + " " + Thread.currentThread().getName());
386 // previewTime = endTime;*/
391 private boolean checkCameraHardware(Context context) {
392 return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
395 private static Camera getCameraInstance(){
398 Log.e(TAG, "Open Camera");
400 } catch (Exception e){
406 private void configCamera(Camera camera){
407 Camera.Parameters paras = camera.getParameters();
408 gLogger.error("Supported Picture Sizes:");
409 for (Camera.Size cc : paras.getSupportedPictureSizes()){
410 gLogger.error(cc.width + "x" + cc.height);
412 gLogger.error("Supported Preview fps range:");
413 for(int[] i : paras.getSupportedPreviewFpsRange()){
414 gLogger.error("[" + i[0] + "," + i[1] + "]");
416 gLogger.error("Set parameters");
417 camera.setParameters(paras);
418 camera.setDisplayOrientation(0);
419 gLogger.error("Preview Format: " + paras.getPreviewFormat() + ". Size: " + paras.getPreviewSize().width + "x" + paras.getPreviewSize().height);
420 gLogger.error("Picture Format: " + paras.getPictureFormat() + ". Size: " + paras.getPictureSize().width + "x" + paras.getPictureSize().height);
423 camera.setPreviewDisplay(mHolder);
424 } catch (IOException e){
427 camera.setPreviewCallback(this);
430 private void switchToBackground(){
431 Intent i = new Intent();
432 i.setAction(Intent.ACTION_MAIN);
433 i.addCategory(Intent.CATEGORY_HOME);
434 this.startActivity(i);
437 private String getMacAddr() {
438 WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
439 WifiInfo info = manager.getConnectionInfo();
440 return info.getMacAddress().replace(":", ""); //02:00:00:00:00:00 - 020000000000
443 private void loadConfig() {
444 UserInfo info = UserInfo.getConfig();
445 mTextServer.setText(info.server.equals("") ? "rtmp://gpussh.suanzi.ai:1935/myapp" : info.server);
446 mTextUser.setText(info.user.equals("") ? "suanzi" : info.user );
447 mTextCamera.setText(info.cameraId.equals("") ? "001" : info.cameraId);
448 mMacAddr = info.macAddr.equals("") ? this.mMacAddr : info.macAddr;
449 gLogger.debug("loadConfig " + info.toString());
452 private void saveConfig() {
453 UserInfo info = UserInfo.getConfig();
454 info.update(mTextServer.getText().toString(), mTextUser.getText().toString(), mMacAddr, mTextCamera.getText().toString());
455 if(info.saveConfig()) {
456 Toast.makeText(getApplicationContext(), "Config saved", Toast.LENGTH_LONG).show();
458 Toast.makeText(getApplicationContext(), "Error: config saved", Toast.LENGTH_LONG).show();
460 gLogger.error("saveConfig: " + info.toString());
463 private void changePermission(){
465 Log.e(TAG, "change permission");
466 //Process sh = Runtime.getRuntime().exec(new String[]{"su", "-c", "chmod 666 /dev/video0"});
468 Process sh = Runtime.getRuntime().exec("/system/xbin/su", null,null);
469 //Process sh = Runtime.getRuntime().exec("su", null,null);
471 OutputStream os = sh.getOutputStream();
472 os.write(("/system/bin/chmod 666 /dev/video0").getBytes("ASCII"));
473 //os.write(("/system/bin/echo 'wowo' >> /data/local/test").getBytes("ASCII"));
479 }catch (Exception e){