Я пытаюсь транслировать видео с Raspberry Pi в приложение для Android. На стороне сервера написано на Python, как показано ниже:
import socket
import struct
import time
import picamera
client_socket = socket.socket()
client_socket.connect(('192.168.0.126', 8000))
connection = client_socket.makefile('wb')
try:
with picamera.PiCamera() as camera:
camera.resolution = (160, 120)
camera.framerate = 30
time.sleep(2)
start = time.time()
stream = io.BytesIO()
# Use the video-port for captures...
for foo in camera.capture_continuous(stream, 'jpeg',
use_video_port=True):
connection.write(struct.pack('<L', stream.tell()))
connection.flush()
stream.seek(0)
connection.write(stream.read())
if time.time() - start > 30:
break
stream.seek(0)
stream.truncate()
connection.write(struct.pack('<L', 0))
finally:
connection.close()
client_socket.close()
Класс Java на стороне Android, как показано ниже. Я пытаюсь получить изображение и отображать одно и то же кадр за кадром в просмотре изображений в приложении для Android.
package com.example.videostreaming2;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class MainActivity extends AppCompatActivity {
public static final String TAG="VS2";
public DataInputStream dataInputStream;
ImageView imageView;
int len;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public class frame2video extends AsyncTask<byte[],Void, Bitmap>{
protected void onPreExecute(){
imageView=(ImageView)findViewById(R.id.imview);
try{
ServerSocket serverSocket=new ServerSocket(8000);
Socket video_receiver=serverSocket.accept();
while(true){
DataInputStream dataInputStream=new DataInputStream(video_receiver.getInputStream());
len=Integer.parseInt(""+dataInputStream.readInt());
System.out.println(len);
byte[] buffer=new byte[len];
dataInputStream.readFully(buffer,0,buffer.length);
frame2video f2v=new frame2video();
f2v.execute(buffer);
}
}catch (Exception e){
e.printStackTrace();
}
}
protected Bitmap doInBackground(byte[]...buffer){
try {
Bitmap bitmap = BitmapFactory.decodeByteArray(buffer[0], 0, len);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
outputStream.flush();
return bitmap;
}catch(IOException e){
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
imageView.setImageBitmap(bitmap);
imageView.invalidate();
}
}
}
У меня есть два вопроса:
У меня естьнастроить переадресацию портов в android studio, но когда я запускаю приложение Java в эмуляторе и код python на pi, я получаю отказ в соединении (ERR 111) на pi. Я подтвердил, что брандмауэр на моем Mac выключен. Есть ли другой способ протестировать приложение на эмуляторе?
Я подозревал, что проблема может быть связана с настройкой эмулятора, поэтому я подключил свой телефон Android. Теперь, когда я запускаю приложение на своем телефоне (подключенном к моей Mac и Android Studio) и запускаю приложение python на pi, я получаю следующие ошибки в студии:
09/29 21:43:44: Launching 'app' on Essential Products PH-1.
$ adb shell am start -n "com.example.videostreaming2/com.example.videostreaming2.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Waiting for process to come online...
Connected to process 5795 on device 'essential_products-ph_1-PM1LHMA812601675'.
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
W/videostreaming: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist, reflection, allowed)
W/videostreaming: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist, reflection, allowed)
I/AdrenoGLES: QUALCOMM build : 436c23c, I70c9d1ad86
Build Date : 06/19/19
OpenGL ES Shader Compiler Version: EV031.26.14.00
Local Branch : mybranche992c040-71da-f106-bb16-1458d0b52ae8
Remote Branch : quic/gfx-adreno.lnx.1.0.r85-rel
Remote Branch : NONE
Reconstruct Branch : NOTHING
Build Config : C O 9.0.3 AArch64
I/AdrenoGLES: PFP: 0x005ff110, ME: 0x005ff066
W/Gralloc3: mapper 3.x is not supported
на стороне Python я все еще получаю отказано в соединении:
[Errno 111] Connection refused
Подходят ли подход для отображения входящего изображения в режиме просмотра изображений? Есть ли альтернативный подход для отображения потока? Я только начинаю разработку Android, возможно, я делаю глупые ошибки.