µStreamer เป็นเซิร์ฟเวอร์ที่มีน้ำหนักเบาและรวดเร็วมากในการสตรีมวิดีโอ MJPEG จากอุปกรณ์ V4L2 ใด ๆ ไปยังเน็ต เบราว์เซอร์ใหม่ทั้งหมดรองรับรูปแบบวิดีโอนี้แบบเนทีฟ เช่นเดียวกับเครื่องเล่นวิดีโอส่วนใหญ่ เช่น mplayer, VLC เป็นต้น µStreamer เป็นส่วนหนึ่งของโปรเจ็กต์ PiKVM ที่ออกแบบมาเพื่อสตรีมข้อมูลฮาร์ดแวร์ Screencast VGA และ HDMI ด้วยความละเอียดสูงสุดและ FPS ที่เป็นไปได้
µStreamer คล้ายกับ mjpg-streamer มากซึ่งมีปลั๊กอิน input_uvc.so
และ output_http.so
อย่างไรก็ตาม มีความแตกต่างที่สำคัญบางประการ สิ่งสำคัญคือ:
คุณสมบัติ | µStreamer | mjpg-ลำแสง |
---|---|---|
การเข้ารหัส JPEG แบบมัลติเธรด | ||
การเข้ารหัสภาพฮาร์ดแวร์ บนราสเบอร์รี่ Pi | ||
ลักษณะการทำงานเมื่ออุปกรณ์ ถูกตัดการเชื่อมต่อขณะสตรีมมิ่ง | ✔แสดงหน้าจอสีดำ โดย NO SIGNAL อยู่จนกว่าจะเชื่อมต่อใหม่ | ✘ หยุดการสตรีม 1 |
รองรับการกำหนดเวลา DV - ความสามารถในการเปลี่ยนความละเอียด ได้ทันทีโดยสัญญาณต้นทาง | ☹ ใช่บางส่วน 1 | |
ตัวเลือกในการข้ามเฟรมเมื่อสตรีมมิ่ง ภาพนิ่งโดย HTTP เพื่อบันทึกการรับส่งข้อมูล | ✔ 2 | |
สตรีมมิ่งผ่านซ็อกเก็ตโดเมน UNIX | ||
การเปิดใช้งานซ็อกเก็ต Systemd | ||
บันทึกการแก้ไขข้อบกพร่องโดยไม่ต้องคอมไพล์ใหม่ บันทึกสถิติประสิทธิภาพ เข้าถึงพารามิเตอร์การสตรีม HTTP | ||
ตัวเลือกในการให้บริการไฟล์ ด้วยเซิร์ฟเวอร์ HTTP ในตัว | ☹ ไฟล์ปกติเท่านั้น | |
การส่งสัญญาณเกี่ยวกับสถานะสตรีม บน GPIO โดยใช้ libgpiod | ||
เข้าถึงการควบคุมเว็บแคม (โฟกัส, เซอร์โว) และการตั้งค่าต่างๆ เช่น ความสว่างผ่าน HTTP | ||
ความเข้ากันได้กับ API ของ mjpg-streamer | - |
เชิงอรรถ:
1
ก่อนหน้า µStreamer มานานแล้ว ฉันได้แพตช์เพื่อเพิ่มการรองรับ DV-timings ให้กับ mjpg-streamer และเพื่อป้องกันไม่ให้อุปกรณ์หยุดทำงาน อนิจจา แพตช์นี้ยังห่างไกลจากความสมบูรณ์แบบ และฉันไม่สามารถรับประกันได้ว่าจะใช้งานได้ทุกครั้ง - ซอร์สโค้ดของ mjpg-streamer นั้นซับซ้อนมากและโครงสร้างของมันก็เข้าใจยาก เมื่อคำนึงถึงสิ่งนี้ ประกอบกับความต้องการมัลติเธรดและการเร่งความเร็วด้วยฮาร์ดแวร์ JPEG ในอนาคต ฉันจึงตัดสินใจสร้างเซิร์ฟเวอร์สตรีมของตัวเองตั้งแต่เริ่มต้น แทนที่จะรองรับโค้ดแบบเดิม
2
คุณสมบัตินี้ช่วยลดการรับส่งข้อมูลขาออกได้หลายเท่าเมื่อสตรีม HDMI แต่จะเพิ่มการใช้งาน CPU เล็กน้อย แนวคิดก็คือ HDMI เป็นอินเทอร์เฟซดิจิทัลเต็มรูปแบบ และแต่ละเฟรมที่จับภาพสามารถเหมือนกันกับเฟรมก่อนหน้าแบบไบต์ได้ ไม่จำเป็นต้องสตรีมภาพเดียวกันบนเน็ตหลายครั้งต่อวินาที เมื่อเปิดใช้งานตัวเลือก --drop-same-frames=20
µStreamer จะปล่อยเฟรมที่ตรงกันทั้งหมด (โดยจำกัดไว้ที่ 20 เฟรมในแถว) แต่ละเฟรมใหม่จะถูกจับคู่กับเฟรมก่อนหน้าก่อนตามความยาว จากนั้นใช้ memcmp()
หากคุณกำลังจะถ่ายทอดสดจากเว็บแคมหลังบ้านและจำเป็นต้องควบคุม ให้ใช้ mjpg-streamer หากคุณต้องการภาพคุณภาพสูงที่มี FPS สูง - µStreamer เพื่อชัยชนะ
คุณต้องดาวน์โหลด µStreamer ลงบนระบบของคุณและสร้างมันจากแหล่งที่มา
คุณจะต้อง make
, gcc
, libevent
พร้อมรองรับ pthreads
, libjpeg9
/ libjpeg-turbo
และ libbsd
(สำหรับ Linux เท่านั้น)
sudo pacman -S libevent libjpeg-turbo libutil-linux libbsd
sudo apt install libevent-dev libjpeg62-turbo libbsd-dev
เพิ่ม libgpiod-dev
สำหรับ WITH_GPIO=1
และ libsystemd-dev
สำหรับ WITH_SYSTEMD=1
และ libasound2-dev libspeex-dev libspeexdsp-dev libopus-dev
สำหรับ WITH_JANUS=1
libjpeg62-turbo
เป็น libjpeg62-turbo-dev
sudo apt install build-essential libevent-dev libjpeg-dev libbsd-dev
sudo apk add libevent-dev libbsd-dev libjpeg-turbo-dev musl-dev
สร้างด้วย WITH_PTHREAD_NP=0
หากต้องการเปิดใช้งานการสนับสนุน GPIO ให้ติดตั้ง libgpiod และตัวเลือกการส่งผ่าน WITH_GPIO=1
หากคอมไพเลอร์รายงานเกี่ยวกับฟังก์ชันที่หายไป pthread_get_name_np()
(หรือคล้ายกัน) ให้เพิ่มตัวเลือก WITH_PTHREAD_NP=0
(เปิดใช้งานตามค่าเริ่มต้น) สำหรับข้อผิดพลาดที่คล้ายกันกับ setproctitle()
ให้เพิ่มตัวเลือก WITH_SETPROCTITLE=0
กระบวนการที่สะดวกที่สุดคือการโคลนพื้นที่เก็บข้อมูล µStreamer Git ลงบนระบบของคุณ หากคุณไม่ได้ติดตั้ง Git และไม่ต้องการติดตั้งเช่นกัน คุณสามารถดาวน์โหลดและแตกไฟล์ซอร์สจาก GitHub โดยใช้ wget https://github.com/pikvm/ustreamer/archive/refs/heads/master.zip
.
$ git clone --depth=1 https://github.com/pikvm/ustreamer
$ cd ustreamer
$ make
$ ./ustreamer --help
สมมติว่าคุณมีโคลน µStreamer ตามที่กล่าวไว้ข้างต้น คุณสามารถอัปเดต µStreamer ได้ดังต่อไปนี้
$ cd ustreamer
$ git pull
$ make clean
$ make
สำหรับการเข้ารหัสฮาร์ดแวร์ M2M บน Raspberry Pi คุณต้องมีเคอร์เนลอย่างน้อย 5.15.32 การสนับสนุน OpenMAX และ MMAL บนเคอร์เนลรุ่นเก่าเลิกใช้แล้วและถูกลบออก
หากไม่มีข้อโต้แย้ง ustreamer
จะพยายามเปิด /dev/video0
ด้วยความละเอียด 640x480 และเริ่มสตรีมบน http://127.0.0.1:8080
คุณสามารถแทนที่พฤติกรรมนี้ได้โดยใช้พารามิเตอร์ --device
, --host
และ --port
ตัวอย่างเช่น หากต้องการสตรีมไปทั่วโลก ให้รัน:
# ./ustreamer --device=/dev/video1 --host=0.0.0.0 --port=80
❗ โปรดทราบว่าเนื่องจากคำขอข้ามโดเมน µStreamer v2.0 ถูกปิดใช้งานโดยค่าเริ่มต้นด้วยเหตุผลด้านความปลอดภัย หากต้องการเปิดใช้งานลักษณะการทำงานแบบเก่า ให้ใช้ตัวเลือก --allow-origin=*
วิธีที่แนะนำในการรัน µStreamer ด้วยอุปกรณ์จับภาพที่ใช้ TC358743 บน Raspberry Pi:
$ ./ustreamer
--format=uyvy # Device input format
--encoder=m2m-image # Hardware encoding on V4L2 M2M driver
--workers=3 # Workers number
--persistent # Suppress repetitive signal source errors (for example when HDMI cable was disconnected)
--dv-timings # Use DV-timings
--drop-same-frames=30 # Save the traffic
❗ โปรดทราบว่าในการใช้ --drop-same-frames
สำหรับเบราว์เซอร์ที่แตกต่างกัน คุณต้องใช้พารามิเตอร์ URL /stream
เฉพาะเจาะจง (ดู URL /
สำหรับรายละเอียด)
คุณสามารถดูรายการตัวเลือกทั้งหมดได้ตลอดเวลาด้วย ustreamer --help
เพิ่มบรรทัดต่อไปนี้ใน /boot/firmware/usercfg.txt:
gpu_mem=128
dtoverlay=tc358743
ตรวจสอบขนาดของ CMA:
$ dmesg | grep cma-reserved
[ 0.000000] Memory: 7700524K/8244224K available (11772K kernel code, 1278K rwdata, 4320K rodata, 4096K init, 1077K bss, 281556K reserved, 262144K cma-reserved)
หากมีขนาดเล็กกว่า 128M ให้เพิ่มสิ่งต่อไปนี้ใน /boot/firmware/cmdline.txt:
cma=128M
บันทึกการเปลี่ยนแปลงและรีบูต
เริ่มคอนเทนเนอร์:
$ docker run --device /dev/video0:/dev/video0 -e EDID=1 -p 8080:8080 pikvm/ustreamer:latest
จากนั้นเข้าถึงเว็บอินเตอร์เฟสที่พอร์ต 8080 (เช่น http://raspberrypi.local:8080)
$ docker run --rm pikvm/ustreamer:latest
--format=uyvy
--workers=3
--persistent
--dv-timings
--drop-same-frames=30
เพิ่ม -e EDID=1
เพื่อตั้งค่า HDMI EDID ก่อนเริ่ม ustreamer ใช้ร่วมกับ -e EDID_HEX=xx
เพื่อระบุข้อมูล EDID ที่กำหนดเอง
ตัวอย่างการใช้งานสำหรับกล้อง Raspberry Pi v3 (จำเป็นต้องมี libcamerify
ซึ่งอยู่ใน libcamera-tools
และ libcamera-v4l2
(ติดตั้งทั้งสองอย่าง) บน Raspbian):
$ sudo modprobe bcm2835-v4l2
$ libcamerify ./ustreamer --host :: --encoder=m2m-image
สำหรับกล้อง v2 คุณสามารถใช้เคล็ดลับเดียวกันกับ libcamerify
แต่เปิดใช้งานโหมดกล้องรุ่นเก่าใน raspi-config
ตัวอย่างการใช้งานกล้อง Raspberry Pi v1:
$ sudo modprobe bcm2835-v4l2
$ ./ustreamer --host :: -m jpeg --device-timeout=5 --buffers=3 -r 2592x1944
❗ โปรดทราบว่ากล้องรุ่นใหม่จะมีความละเอียดสูงสุดที่แตกต่างกัน คุณสามารถดูความละเอียดที่รองรับได้ที่เอกสารประกอบของ PiCamera
❗ หากคุณได้รับเฟรมเรตต่ำ อาจเป็นไปได้ว่ากล้องอาจเปลี่ยนไปใช้โหมดภาพถ่าย ซึ่งทำให้เฟรมเรตต่ำ (แต่ได้ภาพคุณภาพสูงกว่า) เนื่องจาก bcm2835-v4l2
สลับไปที่โหมดรูปภาพที่ความละเอียดสูงกว่า 1280x720
หากต้องการแก้ไขปัญหานี้ ให้ส่งพารามิเตอร์โมดูล max_video_width
และ max_video_height
ดังนี้:
$ modprobe bcm2835-v4l2 max_video_width=2592 max_video_height=1944
µStreamer รองรับการสตรีมที่มีประสิทธิภาพแบนด์วิธโดยใช้การบีบอัด H.264 และเซิร์ฟเวอร์ Janus WebRTC ดูคู่มือการรวม Janus สำหรับรายละเอียดทั้งหมด
เมื่อ uStreamer อยู่หลังพร็อกซี Nginx ลักษณะการบัฟเฟอร์ของมันจะทำให้เกิดเวลาแฝงในสตรีมวิดีโอ เป็นไปได้ที่จะปิดการใช้งานการบัฟเฟอร์ของ Nginx เพื่อกำจัดเวลาแฝงเพิ่มเติม:
location /stream {
postpone_output 0;
proxy_buffering off ;
proxy_ignore_headers X-Accel-Buffering;
proxy_pass http://ustreamer;
}
ยูทิลิตี้ v4l2 มีเครื่องมือในการจัดการการตั้งค่าและข้อมูลเว็บแคม USB สามารถใช้สคริปต์เพื่อทำการปรับเปลี่ยนและรันด้วยตนเองหรือกับ cron ทำงานใน cron เพื่อเปลี่ยนการตั้งค่าการรับแสงในบางช่วงเวลาของวัน แพคเกจนี้มีอยู่ในลีนุกซ์ทุกรุ่นและมักเรียกว่า v4l-utils
v4l2-ctl --list-devices
v4l2-ctl -d /dev/video0 --list-ctrls
v4l2-ctl -d /dev/video0 --list-formats-ext
v4l2-ctl -d /dev/video0 --get-ctrl=exposure_auto
v4l2-ctl -d /dev/video0 --set-ctrl=exposure_auto=1
คุณสามารถดูตัวอย่างเพิ่มเติมได้ที่นี่ เอกสารมีอยู่ใน man v4l2-ctl
ลิขสิทธิ์ (C) 2018-2024 โดย Maxim Devaev [email protected]
โปรแกรมนี้เป็นซอฟต์แวร์เสรี: คุณสามารถแจกจ่ายซ้ำและ/หรือแก้ไขได้ภายใต้เงื่อนไขของ GNU General Public License ตามที่เผยแพร่โดย Free Software Foundation ไม่ว่าจะเป็นเวอร์ชัน 3 ของใบอนุญาต หรือ (ตามตัวเลือกของคุณ) เวอร์ชันที่ใหม่กว่า
โปรแกรมนี้เผยแพร่ด้วยความหวังว่าจะมีประโยชน์ แต่ไม่มีการรับประกันใดๆ โดยไม่มีการรับประกันโดยนัยถึงความสามารถในการค้าขายหรือความเหมาะสมสำหรับวัตถุประสงค์เฉพาะ ดูใบอนุญาตสาธารณะทั่วไปของ GNU สำหรับรายละเอียดเพิ่มเติม
คุณควรได้รับสำเนาของ GNU General Public License พร้อมกับโปรแกรมนี้ ถ้าไม่ โปรดดู https://www.gnu.org/licenses/