728x90
[1] 카메라 스트리밍
1. 기본 구조 예제
1) 라즈베리파이
① 카메라 모듈 생성
mycamera.py
# mycamera.py
import io
import threading
import picamera
import time
class MyCamera:
frame = None
thread = None
# streaming메소드를 쓰레드로 동작시키며 스트리밍되는 frame을 외부로 보내는 메소드
def getStreaming(self):
if MyCamera.thread is None:
MyCamera.thread = threading.Thread(target=self.streaming)
MyCamera.thread.start()
while self.frame is None:
time.sleep(0)
return self.frame
# Thread로 실행흐름을 분리 - picamera로 찍은 영상을 frame 단위로 보내는 메소드
# 인스턴스메소드, 클래스메소드(@classmethod 표시)
# io 모듈은 다양한 i/o처리를 위해 제공되는 모듈
# 텍스트, 바이너리, raw 데이터
# 텍스트
# - string -> f = open("myfile.txt", "rt")
# - io.StringIO(메모리 스트림)
# 바이너리
# - f = open("myimg.jpg", "rb")
# - 인메모리 바이너리스트림 -> io.BytesIO()
@classmethod
def streaming(c):
with picamera.PiCamera() as camera:
camera.resolution = (320, 240)
camera.hflip = True
camera.vflip = True
camera.start_preview()
time.sleep(2)
stream = io.BytesIO()
for f in camera.capture_continuous(stream, "jpeg", use_video_port=True):
stream.seek(0)
c.frame = stream.read()
# 다음 캡쳐를 위한 준비 - 파일의 내용을 비우기
stream.seek(0)
stream.truncate()
② MQTT 모듈 생성 및 모듈 내 테스트 코드
mymqtt.py
# mymqtt.py
import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
from threading import Thread
import mycamera
class MqttWorker:
def __init__(self):
self.client = mqtt.Client()
self.client.on_connect = self.on_connect
self.client.on_message = self.on_message
self.camera = mycamera.MyCamera()
def mymqtt_connect(self):
try:
print("브로커 연결 시작하기")
self.client.connect("XXX.XXX.XXX.XXX", 1883, 60)
self.client.loop_forever()
except KeyboardInterrupt:
pass
finally:
print("종료")
def on_connect(self, client, userdata, flags, rc):
print("connect..."+str(rc))
if rc == 0:
self.client.subscribe("web")
else:
print("연결 실패.....")
def on_message(self, client, userdata, message):
try:
myval = message.payload.decode("utf-8")
print(message.topic+"-----"+myval)
if myval == "start":
while True:
frame = self.camera.getStreaming()
publish.single("mycamera", frame, hostname="172.30.1.57")
except:
pass
finally:
pass
if __name__ == "__main__":
mymqtt = MqttWorker()
mymqtt.mymqtt_connect()
2) Web
mqttvideo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js"
type = "text/javascript"> </script>
<script type="text/javascript">
var host = "XXX.XXX.XXX.XXX"
var port = 9001
function onConnect(){
console.log("접속완료")
// 영상데이터가 전송될 때까지 대기
mqtt.subscribe("mycamera")
// 웹페이지 접속하자마자 메시지 보내기
message = new Paho.MQTT.Message("start");
// topic 설정
message.destinationName = "web";
// MQTT 메시지 보내기 - publish
mqtt.send(message);
}
function onFailure(){
console.log("접속실패")
}
function onMessageArrived(msg){
//console.log("====="+msg.payloadBytes+"====<br>")
// 전송되는 payloadBytes를 이미지로 만들어서 이미지태그에 연결
// 바이너리데이터를 인코딩해야 할 경우 Base64
// 자바스크립트에서 문자열을 base64로 인코드하려면 btoa 메소드를 이용해서 변환
// broker로부터 전송받은 payloadBytes를 btoa메소드에서 변경할 수 있도록 문자열로 변환해서 전달
document.getElementById("myimg").src = "data:image/jpeg;base64,"+btoa(String.fromCharCode.apply(null, msg.payloadBytes))
}
function MQTTConnect(){
console.log("mqtt접속:"+host+","+port)
mqtt = new Paho.MQTT.Client(host, port, "Video Client")
var options = {
timeout: 3,
onSuccess: onConnect,
onFailure: onFailure,
}
mqtt.onMessageArrived = onMessageArrived
mqtt.connect(options)
}
</script>
</head>
<body>
<script>MQTTConnect()</script>
<h1>MQTT와 웹소켓 테스트</h1>
<img id="myimg" src="#" width="800" height="600">
</body>
</html>
- 끝 -
728x90
'프로젝트형 IoT 서비스 개발 4회차 > 3. 게이트웨이 디바이스 제어' 카테고리의 다른 글
[Day62] 2022-04-26(화) Kotlin 기본1 - 변수, 함수 - 김서연 강사님 (0) | 2022.04.26 |
---|---|
[Day62] 2022-04-26(화) 안드로이드 개발 준비 - 김서연 강사님 (2) | 2022.04.26 |
[Day61] 2022-04-25(월) Flask 활용 - 김서연 강사님 (0) | 2022.04.25 |
[Day60] 2022-04-22(금) 라즈베리파이9 - 카메라, 이벤트 처리 - 김서연 강사님 (0) | 2022.04.22 |
[Day59] 2022-04-21(목) 라즈베리파이8 - 온습도 센서(DHT11) - 김서연 강사님 (0) | 2022.04.21 |