android手机连接esp32视频

之前无意中买了个esp32的板子 还带了个小摄像头 ,跑了它的例子后可以在电脑上看到视频,下面是记录的使用方法。
esp32摄像头的使用
后来想在手机上直接查看视频,但一直没有成功,直到我看了b站上的稚晖君的一个视频
【自制】吃完的螃蟹不要扔,裹上黑科技,可以做一台火星车~【硬核】

里面刚好用到了esp32的摄像头模块,于是找到他的githup地址,
地址

里面有这个的整个开源项目,copy下来。
第一次跑也没能成功,问题在他使用的摄像头与我的不一样,
根据之前的esp32摄像头的使用例子代码,我的摄像头是
#define CAMERA_MODEL_AI_THINKER
在camera_pins.h中找到与该定义对应的宏
再打开稚晖君的esp32代码,修改其中pins.h中的宏定义与我所使用摄像头定义的一样:

#ifndef PIN_H
#define PIN_H

#define I2C0_SDA 32
#define I2C0_SCL 33

#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27

#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22

#endif

后来还是不行,问题出在就出在android的读写权限上,
所以修改了读写权限 :
android 读写权限问题 :java.io.IOException: Permission denied 解决方法
并修改了其中的一些代码。

去掉esp32代码中不需要的部分,修改后如下:

#include <WiFi.h>
// #include <U8g2lib.h>
#include <I2Cdev.h>
#include <Wire.h>
// #include <MPU6050.h>
#include "Pins.h"
#include "Camera.h"
#include "Motor.h"

const char* ssid = "";  //填你自己的局域网名
const char* password = ""; //局域网密码

WiFiServer server(81);

// OV2640 camera
Camera ov2640;

void setup()
{
	Serial.begin(115200);

	Wire.begin(I2C0_SDA, I2C0_SCL);
	Wire.setClock(400000);

	// while (!mpu6050.testConnection());
	// mpu6050.initialize();

	ov2640.initialize();

	int n = WiFi.scanNetworks();
	Serial.println("scan done");
	if (n == 0)
	{
		Serial.println("no networks found");
	}
	else
	{
		Serial.print(n);
		Serial.println(" networks found");
		for (int i = 0; i < n; ++i)
		{
			// Print SSID and RSSI for each network found
			Serial.print(i + 1);
			Serial.print(": ");
			Serial.print(WiFi.SSID(i));
			Serial.print(" (");
			Serial.print(WiFi.RSSI(i));
			Serial.print(")");
			Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
			delay(10);
		}
	}

	WiFi.begin(ssid, password);

	while (WiFi.status() != WL_CONNECTED)
	{
		delay(500);
		Serial.print(".");
	}
	Serial.println("");
	Serial.println("WiFi connected");

	ov2640.startCameraServer();

	Serial.print("Camera Ready! Use 'http://");
	Serial.print(WiFi.localIP());
	Serial.println("' to connect");

	server.begin();
}


float i = -1;
long heart_beat = 0;
void loop()
{

	Serial.println(analogRead(38));

	WiFiClient client = server.available();   // listen for incoming clients
	if (client)
	{
		// if you get a client,
		Serial.println("New Client.");           // print a message out the serial port
		String currentLine = "";                // make a String to hold incoming data from the client
		while (client.connected())
		{            // loop while the client's connected
			if (client.available())
			{             // if there's bytes to read from the client,
		
			}
		}
	}

	delay(50);
}
String getValue(String data, char separator, int index)
{
	int found = 0;
	int strIndex[] = { 0, -1 };
	int maxIndex = data.length() - 1;

	for (int i = 0; i <= maxIndex && found <= index; i++)
	{
		if (data.charAt(i) == separator || i == maxIndex)
		{
			found++;
			strIndex[0] = strIndex[1] + 1;
			strIndex[1] = (i == maxIndex) ? i + 1 : i;
		}
	}
	return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

android studio代码修改如下:
主要是添加了申请权限部分与去掉了他多余的代码。

package xyz.pengzhihui.esp32ipcam;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;

public class MainActivity extends Activity implements View.OnClickListener
{

    private static final String TAG = "MainActivity::";

    private HandlerThread handlerThread;
    private Handler handler;
    private ImageView imageView;

    private final int DOWNDLOAD = 1;
    private final int REGISTER = 2;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.downloadFile).setOnClickListener(this);
        imageView = findViewById(R.id.img);

        handlerThread = new HandlerThread("http");
        handlerThread.start();
        handler = new HttpHandler(handlerThread.getLooper());
    }


    @Override
    public void onClick(View v)
    {
        switch (v.getId())
        {
            case R.id.downloadFile:
                handler.sendEmptyMessage(DOWNDLOAD);
                break;
            default:
                break;
        }
    }

    //动态申请权限
    public static boolean isGrantExternalRW(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && activity.checkSelfPermission(
                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

            activity.requestPermissions(new String[]{
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
            }, 1);
            return false;
        }
        return true;
    }


    private class HttpHandler extends Handler
    {
        public HttpHandler(Looper looper)
        {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case DOWNDLOAD:
                    downloadFile();
                    break;
                default:
                    break;
            }
        }
    }

    private void downloadFile()
    {
        String downloadUrl = "http://192.168.50.26:80/stream";
        String savePath = "/sdcard/pic.jpg";

        File file = new File(savePath);
        if (file.exists())
        {
            file.delete();
        }

        if(!isGrantExternalRW(this)){
            return;
        }

        BufferedInputStream bufferedInputStream = null;
        FileOutputStream outputStream = null;
        try
        {
            URL url = new URL(downloadUrl);

            try
            {
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setRequestMethod("GET");
                httpURLConnection.setConnectTimeout(1000 * 5);
                httpURLConnection.setReadTimeout(1000 * 5);
                httpURLConnection.setDoInput(true);
                httpURLConnection.connect();

                if (httpURLConnection.getResponseCode() == 200)
                {
                    InputStream in = httpURLConnection.getInputStream();

                    InputStreamReader isr = new InputStreamReader(in);
                    BufferedReader bufferedReader = new BufferedReader(isr);

                    String line;
                    StringBuffer stringBuffer = new StringBuffer();

                    int i = 0;

                    int len;
                    byte[] buffer;

                    while ((line = bufferedReader.readLine()) != null)
                    {
                        if (line.contains("Content-Type:"))
                        {
                            line = bufferedReader.readLine();

                            len = Integer.parseInt(line.split(":")[1].trim());

                            bufferedInputStream = new BufferedInputStream(in);
                            buffer = new byte[len];

                            int t = 0;
                            while (t < len)
                            {
                                t += bufferedInputStream.read(buffer, t, len - t);
                            }

                            bytesToImageFile(buffer, "0A.jpg");

                            final Bitmap bitmap = BitmapFactory.decodeFile("sdcard/0A.jpg");
                            runOnUiThread(new Runnable()
                            {
                                @Override
                                public void run()
                                {
                                    imageView.setImageBitmap(bitmap);
                                }
                            });
                        }


                    }
                }

            } catch (IOException e)
            {
                e.printStackTrace();
            }
        } catch (MalformedURLException e)
        {
            e.printStackTrace();
        } finally
        {
            try
            {
                if (bufferedInputStream != null)
                {
                    bufferedInputStream.close();
                }
                if (outputStream != null)
                {
                    outputStream.close();
                }
            } catch (IOException e)
            {
                e.printStackTrace();
            }
        }

    }

    private void bytesToImageFile(byte[] bytes, String fileName)
    {
        try
        {
            File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + fileName);
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(bytes, 0, bytes.length);
            fos.flush();
            fos.close();
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }


}

最后结果
在这里插入图片描述

  • 9
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 29
    评论
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值