rocnet:cam-fr
Differences
This shows you the differences between two versions of the page.
| Previous revision | |||
| — | rocnet:cam-fr [2025/04/22 11:43] (current) – [Liens] stefanf | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ======Diffusion par caméra====== | ||
| + | [[: | ||
| + | [[: | ||
| + | * [[: | ||
| + | |||
| + | |< >| | ||
| + | ^ [[https:// | ||
| + | \\ | ||
| + | \\ | ||
| + | {{: | ||
| + | |||
| + | \\ | ||
| + | |||
| + | =====Demos===== | ||
| + | * https:// | ||
| + | |||
| + | |||
| + | \\ | ||
| + | =====Python===== | ||
| + | * https:// | ||
| + | * {{: | ||
| + | |||
| + | ====Script Python==== | ||
| + | <code python> | ||
| + | # Web streaming example | ||
| + | # Source code from the official PiCamera package | ||
| + | # http:// | ||
| + | |||
| + | import io | ||
| + | import picamera | ||
| + | import logging | ||
| + | import socketserver | ||
| + | from threading import Condition | ||
| + | from http import server | ||
| + | |||
| + | PAGE=""" | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | < | ||
| + | <img src=" | ||
| + | </ | ||
| + | </ | ||
| + | """ | ||
| + | |||
| + | class StreamingOutput(object): | ||
| + | def __init__(self): | ||
| + | self.frame = None | ||
| + | self.buffer = io.BytesIO() | ||
| + | self.condition = Condition() | ||
| + | |||
| + | def write(self, buf): | ||
| + | if buf.startswith(b' | ||
| + | # New frame, copy the existing buffer' | ||
| + | # clients it's available | ||
| + | self.buffer.truncate() | ||
| + | with self.condition: | ||
| + | self.frame = self.buffer.getvalue() | ||
| + | self.condition.notify_all() | ||
| + | self.buffer.seek(0) | ||
| + | return self.buffer.write(buf) | ||
| + | |||
| + | class StreamingHandler(server.BaseHTTPRequestHandler): | ||
| + | def do_GET(self): | ||
| + | if self.path == '/': | ||
| + | self.send_response(301) | ||
| + | self.send_header(' | ||
| + | self.end_headers() | ||
| + | elif self.path == '/ | ||
| + | content = PAGE.encode(' | ||
| + | self.send_response(200) | ||
| + | self.send_header(' | ||
| + | self.send_header(' | ||
| + | self.end_headers() | ||
| + | self.wfile.write(content) | ||
| + | elif self.path == '/ | ||
| + | self.send_response(200) | ||
| + | self.send_header(' | ||
| + | self.send_header(' | ||
| + | self.send_header(' | ||
| + | self.send_header(' | ||
| + | self.end_headers() | ||
| + | try: | ||
| + | while True: | ||
| + | with output.condition: | ||
| + | output.condition.wait() | ||
| + | frame = output.frame | ||
| + | self.wfile.write(b' | ||
| + | self.send_header(' | ||
| + | self.send_header(' | ||
| + | self.end_headers() | ||
| + | self.wfile.write(frame) | ||
| + | self.wfile.write(b' | ||
| + | except Exception as e: | ||
| + | logging.warning( | ||
| + | ' | ||
| + | self.client_address, | ||
| + | else: | ||
| + | self.send_error(404) | ||
| + | self.end_headers() | ||
| + | |||
| + | class StreamingServer(socketserver.ThreadingMixIn, | ||
| + | allow_reuse_address = True | ||
| + | daemon_threads = True | ||
| + | |||
| + | with picamera.PiCamera(resolution=' | ||
| + | output = StreamingOutput() | ||
| + | #Uncomment the next line to change your Pi's Camera rotation (in degrees) | ||
| + | # | ||
| + | camera.start_recording(output, | ||
| + | try: | ||
| + | address = ('', | ||
| + | server = StreamingServer(address, | ||
| + | server.serve_forever() | ||
| + | finally: | ||
| + | camera.stop_recording() | ||
| + | </ | ||
| + | |||
| + | Démarrer le script avec: | ||
| + | < | ||
| + | python3 cam.py | ||
| + | </ | ||
| + | //Cela utilise environ 5% du processeur sur un RPi 4+.//\\ | ||
| + | |||
| + | Ouvrir l'URL dans le navigateur avec: | ||
| + | < | ||
| + | http:// | ||
| + | </ | ||
| + | Où < | ||
| + | |||
| + | ====Sortie du serveur WEB Python==== | ||
| + | <code html> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | < | ||
| + | <img src=" | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | </ | ||
| + | |||
| + | \\ | ||
| + | =====Visionneuses===== | ||
| + | ====Texte==== | ||
| + | Pour activer la diffusion MJPEG dans un objet texte, Le contenu du texte doit être défini à: | ||
| + | < | ||
| + | mjpg:< | ||
| + | </ | ||
| + | Par exemple: | ||
| + | < | ||
| + | mjpg: | ||
| + | </ | ||
| + | |||
| + | ====Manette de locomotive==== | ||
| + | Définir la caméra hôte et le port dans l' | ||
| + | \\ | ||
| + | =====Liens===== | ||
| + | * https:// | ||
| + | * https:// | ||
| + | * https:// | ||
| + | ====Solutions IE==== | ||
| + | MS IE ne supporte pas la diffusion de vidéo mjpg. | ||
| + | * https:// | ||
| + | |||
| + | \\ | ||
| + | =====Scission===== | ||
| + | < | ||
| + | 00000130: 55 E6 9D 09 E3 78 60 4E 31 81 BB 05 94 12 A3 38 |U....x`N1......8| | ||
| + | 00000140: 27 6B 74 23 D3 03 35 B5 2E 6E 58 B6 BF AD 46 D3 |' | ||
| + | 00000150: B6 FB 7E 07 FF D9 0D 0A 2D 2D 46 52 41 4D 45 0D |..~.....--FRAME.| | ||
| + | 00000160: 0A 43 6F 6E 74 65 6E 74 2D 54 79 70 65 3A 20 69 |.Content-Type: | ||
| + | 00000170: 6D 61 67 65 2F 6A 70 65 67 0D 0A 43 6F 6E 74 65 |mage/ | ||
| + | 00000180: 6E 74 2D 4C 65 6E 67 74 68 3A 20 31 32 35 32 34 |nt-Length: 12524| | ||
| + | 00000190: 33 0D 0A 0D 0A FF D8 FF DB 00 84 00 01 01 01 01 |3...............| | ||
| + | 000001A0: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................| | ||
| + | 000001B0: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 02 02 |................| | ||
| + | | ||
| + | | ||
| + | 00000120: 8D B9 66 EE EF AD 96 DD 74 E4 76 DF FA 63 FA AD |..f.....t.v..c..| | ||
| + | 00000130: 29 2D 62 AD A6 AA FA FC B9 B4 F9 9F FF D9 0D 0A |)-b.............| | ||
| + | 00000140: 2D 2D 46 52 41 4D 45 0D 0A 43 6F 6E 74 65 6E 74 |--FRAME..Content| | ||
| + | 00000150: 2D 54 79 70 65 3A 20 69 6D 61 67 65 2F 6A 70 65 |-Type: image/jpe| | ||
| + | 00000160: 67 0D 0A 43 6F 6E 74 65 6E 74 2D 4C 65 6E 67 74 |g..Content-Lengt| | ||
| + | 00000170: 68 3A 20 34 37 30 37 37 0D 0A 0D 0A FF D8 FF DB |h: 47077........| | ||
| + | 00000180: 00 84 00 01 01 01 01 01 01 01 01 01 01 01 01 01 |................| | ||
| + | 00000190: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................| | ||
| + | 000001A0: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 |................| | ||
| + | |||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | Source: https:// | ||
| + | <code python> | ||
| + | import cv2 | ||
| + | import urllib | ||
| + | import numpy as np | ||
| + | |||
| + | stream = urllib.urlopen(' | ||
| + | bytes = '' | ||
| + | while True: | ||
| + | bytes += stream.read(1024) | ||
| + | a = bytes.find(' | ||
| + | b = bytes.find(' | ||
| + | if a != -1 and b != -1: | ||
| + | jpg = bytes[a: | ||
| + | bytes = bytes[b+2:] | ||
| + | i = cv2.imdecode(np.fromstring(jpg, | ||
| + | cv2.imshow(' | ||
| + | if cv2.waitKey(1) == 27: | ||
| + | exit(0) | ||