IoT Video Streaming Series | Practical Streaming with USB Camera on macOS

Objective: Stream from a USB camera to ZLMediaKit on macOS, covering environment setup, device recognition, streaming commands, and playback verification.

1. Environment Setup

1.1 Install ffmpeg

Due to compatibility issues between macOS 15 pre-release and Homebrew, it is recommended to download the official precompiled version directly:

# Download the official precompiled version
curl -L -o ffmpeg.zip "https://evermeet.cx/ffmpeg/getrelease/zip"
unzip ffmpeg.zip
sudo mv ffmpeg /usr/local/bin/
# Verify installation
ffmpeg -version

1.2 Start ZLMediaKit Container

# Start the container (ensure port mapping is correct)
docker run -d --name zlmedia \  
 -p 1935:1935 -p 8082:80 -p 8554:554 -p 10000-10010:10000-10010/udp \  
 -e TZ=Asia/Shanghai zlmediakit/zlm:master
# Check port mapping
docker ps --format 'table {{.Names}}\t{{.Ports}}' | grep zlmedia

1.3 Get API Secret

# Get secret
docker exec -it zlmedia grep -n 'secret' /opt/media/conf/config.ini
# Verify API
curl 'http://127.0.0.1:8082/index/api/getMediaList?secret=YOUR_SECRET'

2. Device Recognition and Configuration

2.1 View Available Devices

# List all audio and video devices
ffmpeg -f avfoundation -list_devices true -i ""

2.2 Device Index Explanation

Sample output:

[AVFoundation indev @ 0x7f9863104940] AVFoundation video devices:
[AVFoundation indev @ 0x7f9863104940] [0] FaceTime HD Camera (Built-in)
[AVFoundation indev @ 0x7f9863104940] [1] Q8 HD Webcam
[AVFoundation indev @ 0x7f9863104940] [2] Capture screen 0
[AVFoundation indev @ 0x7f9863104940] [3] Capture screen 1
[AVFoundation indev @ 0x7f9863104940] AVFoundation audio devices:
[AVFoundation indev @ 0x7f9863104940] [0] WeMeet Audio Device
[AVFoundation indev @ 0x7f9863104940] [1] Q8 HD Webcam
[AVFoundation indev @ 0x7f9863104940] [2] MacBook Pro Microphone
  • Video Device Index: 0=Built-in Camera, 1=USB Camera
  • Audio Device Index: 0=WeMeet, 1=USB Camera Microphone, 2=Built-in Microphone

2.3 Test Device Capture

# Test USB Camera (5 seconds recording)
ffmpeg -f avfoundation -framerate 25 -video_size 1280x720 \  
 -i "1:2" -t 5 -c:v libx264 -preset veryfast \  
 -pix_fmt yuv420p test_usb_camera.mp4
# Play test file
open test_usb_camera.mp4
# Test Built-in Camera
ffmpeg -f avfoundation -framerate 25 -video_size 1280x720 -i "0:0" -t 5 -c:v libx264 -preset veryfast -pix_fmt yuv420p test_builtin_camera.mp4
# Play test file
open test_builtin_camera.mp4

3. Streaming Commands

3.1 USB Camera Streaming (Recommended)

# Use USB Camera (Device 1) + Built-in Microphone (Device 2)
ffmpeg -f avfoundation -framerate 25 -video_size 1280x720 \  
 -i "1:2" -c:v libx264 -preset veryfast -tune zerolatency \  
 -pix_fmt yuv420p -profile:v baseline \  
 -x264-params keyint=50:min-keyint=50:scenecut=0 \  
 -c:a aac -b:a 128k -f flv rtmp://127.0.0.1:1935/live/usb_camera

3.2 Built-in Camera Streaming (Recommended)

# Use Built-in Camera (Device 0) + Built-in Microphone (Device 0)
# Recommended command - best compatibility with Safari (verified)
ffmpeg -f avfoundation -framerate 25 -video_size 1280x720 \  
 -i "0:0" -c:v libx264 -preset veryfast -tune zerolatency \  
 -pix_fmt yuv420p -profile:v baseline -level 3.1 \  
 -x264-params keyint=50:min-keyint=50:scenecut=0:bframes=0 \  
 -c:a aac -b:a 128k -f flv rtmp://127.0.0.1:1935/live/builtin_camera
# Alternative command - high quality but less compatibility
ffmpeg -f avfoundation -framerate 25 -video_size 1280x720 \  
 -i "0:0" -c:v libx264 -preset veryfast -tune zerolatency \  
 -pix_fmt uyvy422 -profile:v high422 \  
 -x264-params keyint=50:min-keyint=50:scenecut=0 \  
 -c:a aac -b:a 128k -f flv rtmp://127.0.0.1:1935/live/builtin_camera_hq

3.3 Parameter Explanation

  • <span>-f avfoundation</span>: macOS native capture framework
  • <span>-i "0:0"</span>: Built-in Camera (Device 0) + Built-in Microphone (Device 0)
  • <span>-i "1:2"</span>: USB Camera (Device 1) + Built-in Microphone (Device 2) – requires USB camera
  • <span>-framerate 25</span>: 25fps
  • <span>-video_size 1280x720</span>: 720p resolution
  • <span>-pix_fmt yuv420p</span>: best compatibility pixel format (supported by Safari)
  • <span>-profile:v baseline</span>: WebRTC compatible
  • <span>-level 3.1</span>: H.264 level, ensures compatibility
  • <span>-bframes=0</span>: disable B-frames to reduce latency
  • <span>-tune zerolatency</span>: low latency optimization
  • <span>-x264-params keyint=50:min-keyint=50:scenecut=0</span>: fixed GOP size

4. Verify Streaming

4.1 View Online Streams

# View online stream list
curl 'http://127.0.0.1:8082/index/api/getMediaList?secret=YOUR_SECRET' | jq
# Expected output includes multi-protocol entries for usb_camera or builtin_camera

4.2 Playback Addresses

After successful streaming, the following addresses can be used for playback (note that the addresses for external and built-in cameras are different):

  • HLS:

    • Direct playback in Safari:<span>http://127.0.0.1:8082/live/builtin_camera/hls.m3u8</span>
    • Chrome using hls.js:<span>http://127.0.0.1:8082/live/builtin_camera/hls.m3u8</span>
  • HTTP-FLV:

    • Player:<span>http://127.0.0.1:8082/live/builtin_camera.live.flv</span>
    • Test command:<span>ffplay -fflags nobuffer -flags low_delay -i http://127.0.0.1:8082/live/builtin_camera.live.flv</span>
  • RTMP:

    • VLC/ffplay:<span>rtmp://127.0.0.1:1935/live/builtin_camera</span>
  • RTSP:

    • VLC:<span>rtsp://127.0.0.1:8554/live/builtin_camera</span>

5. Common Issues and Optimizations

5.1 Troubleshooting Streaming Failures

  • Permission Issues: The first time using the camera, macOS will prompt for permission, which needs to be granted
  • Device Index Errors: Ensure the correct device index is used (check first with <span>-list_devices</span>)
  • Encoding Parameters: If streaming is choppy, consider lowering the resolution or frame rate

5.2 Performance Optimization

# Lower resolution (if choppy)
-video_size 640x480
# Lower frame rate (if choppy)
-framerate 15
# Lower bitrate (if network is limited)
-b:v 1000k
# Disable audio (if not needed)
-an

6. Verification Checklist

  • [ ] ffmpeg installed successfully (<span>ffmpeg -version</span>)
  • [ ] ZLMediaKit container running normally (<span>docker ps</span>)
  • [ ] Device recognized correctly (<span>ffmpeg -f avfoundation -list_devices true -i ""</span>)
  • [ ] Streaming successful (<span>getMediaList</span> shows streams)
  • [ ] Playback works in Safari (<span>http://127.0.0.1:8082/live/builtin_camera/hls.m3u8</span>)
  • [ ] Multi-device playback works (HLS/FLV/RTMP/RTSP)

7. Extended Applications

  • Multiple Cameras: Can stream multiple cameras to different stream names simultaneously
  • Recording: ZLMediaKit supports automatic recording of HLS/MP4
  • Transcoding: Real-time transcoding can be performed during streaming
  • Authentication: Streaming and playback authentication can be added

– END –

Leave a Comment