我正在尝试将视频从树莓派流式传输到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()
android端的Java类如下。我正在尝试检索图像并在android应用程序的imageview中逐帧显示相同的帧。
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应用程序,并且在pi上运行python代码时,我在pi上拒绝连接(ERR 111)。我已确认Mac上的防火墙已关闭。还有另一种方法可以在模拟器上测试应用程序吗?
我怀疑问题可能与模拟器设置有关,所以我插入了Android手机。现在,当我在手机上运行该应用程序(已连接到Mac和android studio)并在pi上运行python应用程序时,在Studio中出现以下错误:
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
在imageview中显示传入图像的方法可以吗?是否有其他方法来显示流?我几乎还没有开始进行android开发,我可能会犯一些愚蠢的错误。