This guide shows how to add CarPlay interface display to your GearBox Flask project.
JavaScript Files (in static/js/):
carplay-video-handler.js- Handles video streaming and H.264 decoding
Updated Files:
templates/index.html- Add video element and jMuxer librarystatic/js/main.js- Add video handler integrationstatic/css/style.css- Add video section styling
Add to your HTML <head>:
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jmuxer@2.0.3/dist/jmuxer.min.js"></script>iPhone/Dongle → USB Bulk Transfer → CarPlayVideoHandler → jMuxer → <video> element
-
jMuxer Library
- Decodes H.264 video in browser
- Handles MPEG-TS muxing
- Renders to HTML5 video element
-
CarPlayVideoHandler Class
- Manages USB video endpoint
- Reads video data continuously
- Parses video packets (4-byte duration + H.264 data)
- Feeds data to jMuxer
-
Video Data Format
[4 bytes: duration (little-endian)] [H.264 NAL units]
# In your GearBox project directory
cp carplay-video-handler.js static/js/
cp carplay-styles.css static/css/Replace your templates/index.html with the updated version, or manually add:
<!-- Add to video section -->
<section class="card" id="carplay-section" style="display: none;">
<h2>CarPlay Display</h2>
<div class="video-container">
<video id="carplay-video" controls autoplay
style="width: 100%; max-width: 1280px; background: #000;">
</video>
</div>
<div class="carplay-controls">
<button id="start-carplay-btn" class="btn btn-success">Start CarPlay</button>
<button id="stop-carplay-btn" class="btn btn-danger" style="display: none;">Stop CarPlay</button>
</div>
</section>
<!-- Add before closing </body> -->
<script src="https://cdn.jsdelivr.net/npm/jmuxer@2.0.3/dist/jmuxer.min.js"></script>
<script src="{{ url_for('static', filename='js/carplay-video-handler.js') }}"></script>Add after your existing initialization:
// Initialize video handler
const videoHandler = new CarPlayVideoHandler();
// In DOMContentLoaded
videoHandler.initializeVideoPlayer('carplay-video');
// After successful device connection
videoHandler.setDevice(device);
carplaySection.style.display = 'block';
// Add button handlers
startCarplayBtn.addEventListener('click', async () => {
await videoHandler.startVideoStream();
startCarplayBtn.style.display = 'none';
stopCarplayBtn.style.display = 'inline-block';
});
stopCarplayBtn.addEventListener('click', () => {
videoHandler.stopVideoStream();
stopCarplayBtn.style.display = 'none';
startCarplayBtn.style.display = 'inline-block';
});Add the video styles from carplay-styles.css to your static/css/style.css
The handler auto-detects the video endpoint (usually endpoint 2 or 3). If needed, manually specify:
videoHandler.transferInEndpoint = 3; // Force endpoint 3Adjust jMuxer configuration in carplay-video-handler.js:
this.jmuxer = new JMuxer({
node: videoElementId,
mode: 'video',
maxDelay: 100, // Latency (ms)
fps: 60, // Target FPS
flushingTime: 100, // Buffer flush interval
debug: false // Enable debug logs
});Adjust USB transfer buffer size for higher quality:
const result = await this.device.transferIn(
this.transferInEndpoint,
131072 // Increase from 65536 for 4K
);- Check browser console for errors
- Verify endpoint number: Try endpoints 2, 3, or 4
- Check USB permissions
- Ensure dongle is in CarPlay mode (phone connected)
- Increase buffer size
- Adjust
maxDelayandflushingTimein jMuxer - Check USB connection quality
- Reduce FPS setting
- USB cable issue
- Power supply insufficient
- Dongle needs reset
- Phone not connected to dongle
- CarPlay not initialized on dongle
- Wrong video endpoint
- Start Flask server:
python app.py - Open
https://localhost:5000 - Click "Detect Carlinkit Dongle"
- Select device and grant permissions
- Connect iPhone to dongle (CarPlay should start on phone)
- Click "Start CarPlay" button
- Video should appear in browser
Send touch events to dongle for interaction:
// In CarPlayVideoHandler
async sendTouch(x, y, action) {
// action: 0=down, 1=move, 2=up
const touchData = new Uint8Array([/* touch command format */]);
await this.device.transferOut(1, touchData);
}Capture and play audio from dongle:
// Use Web Audio API
const audioContext = new AudioContext();
// Process audio packets from dongleDynamically adjust video based on screen size.
- jMuxer docs: https://github.com/samirkumardas/jmuxer
- WebUSB API: https://developer.mozilla.org/en-US/docs/Web/API/USB
- react-carplay source: https://github.com/rhysmorgan134/react-carplay
- node-carplay: https://github.com/rhysmorgan134/node-carplay
- Test video streaming with your dongle
- Add touch interaction for full CarPlay control
- Implement audio streaming
- Add error recovery and reconnection logic
- Optimize for your target resolution/FPS