基于JavaScript与Linux/Jackd的PC系统音频跨网流向手机浏览器方案咨询
Absolutely doable! I’ve set up a similar setup before for streaming audio from a headless Linux box to my phone, so I can walk you through every step clearly. Here’s how to pull it off with JACK (or ALSA) on the server and the Web Audio API in your browser:
The core flow is simple:
- Capture your Linux PC’s system audio into JACK/ALSA
- Encode the raw audio into a browser-compatible format (Opus is ideal for low latency and quality)
- Stream the encoded audio over your local network (either via HTTP HLS for broad compatibility or WebSocket for low latency)
- Receive and decode the stream on your phone’s browser using the Web Audio API or native media playback
Let’s start with setting up the headless PC:
1. Install Dependencies
For Debian/Ubuntu-based systems, run these commands to get the required tools:
- Install JACK and Pulseaudio-JACK bridge:
sudo apt install jackd2 pulseaudio-module-jack qjackctl - Install FFmpeg for audio encoding and streaming:
sudo apt install ffmpeg - (Optional) Install
websocketdfor low-latency WebSocket streaming:sudo apt install websocketd(or compile from source if it’s not in your repo)
2. Route System Audio to JACK
Most Linux systems use Pulseaudio by default, so we need to connect it to JACK:
- Load the JACK sink/source modules:
pactl load-module module-jack-sink channels=2 pactl load-module module-jack-source channels=2 - Set JACK as your default audio output:
You can verify the connection withpactl set-default-sink jack_outjack_lsp—you should seesystem:capture_1andsystem:capture_2listed as input sources.
If you prefer using ALSA directly (no JACK), you can skip the above and use arecord to capture from your default ALSA device, but JACK offers more flexibility for audio routing.
3. Stream the Audio
You have two solid options here—pick the one that fits your latency needs:
Option A: HTTP HLS (Broad Browser Compatibility)
HLS is supported by almost all modern browsers and has reliable playback, though it has a small latency (~5-10 seconds).
- Create a directory to serve the HLS files:
sudo mkdir -p /var/www/html/audio-stream - Run FFmpeg to encode JACK audio into HLS segments:
ffmpeg -f jack -i system:capture_1 -c:a opus -b:a 128k -f hls -hls_time 2 -hls_list_size 5 -hls_flags delete_segments /var/www/html/audio-stream/stream.m3u8-f jack -i system:capture_1: Pull audio from JACK’s system capture device-c:a opus: Encode with Opus (high quality, low bandwidth)-hls_time 2: Create 2-second audio segments-hls_flags delete_segments: Auto-clean old segments to save disk space
- Start a simple HTTP server to serve the stream:
Now your stream is available atcd /var/www/html && python3 -m http.server 80http://pc1/audio-stream/stream.m3u8
Option B: WebSocket (Low-Latency Real-Time Streaming)
If you want near-real-time audio (~1-2 seconds latency), WebSocket is the way to go:
- Create a bash script
audio-stream.shto pipe JACK audio to FFmpeg:#!/bin/bash ffmpeg -f jack -i system:capture_1 -c:a opus -f ogg - - Make the script executable:
chmod +x audio-stream.sh - Start websocketd to serve the stream over WebSocket:
Your WebSocket stream is now available atwebsocketd --port=8080 ./audio-stream.shws://pc1:8080
Now set up the browser client on your phone:
Option 1: HLS Stream Client
This is the simplest approach—most browsers support HLS natively, so you can use a basic HTML audio tag:
<!DOCTYPE html> <html> <head> <title>PC Audio Stream</title> </head> <body> <h1>PC Audio Stream</h1> <audio controls autoplay style="width: 100%;"> <source src="http://pc1/audio-stream/stream.m3u8" type="application/x-mpegURL"> Oops! Your browser doesn't support HLS streaming. </audio> </body> </html>
Save this as index.html on your PC’s /var/www/html directory, then visit http://pc1 on your phone’s browser.
Option 2: WebSocket + Web Audio API (Low Latency)
For real-time playback, use the Web Audio API with Media Source Extensions to decode the Opus/Ogg stream:
<!DOCTYPE html> <html> <head> <title>Real-Time PC Audio Stream</title> </head> <body> <h1>Real-Time PC Audio Stream</h1> <button id="startBtn" style="padding: 10px 20px; font-size: 16px;">Start Streaming</button> <script> const startBtn = document.getElementById('startBtn'); let audioContext; let mediaSource; startBtn.addEventListener('click', async () => { // Initialize Web Audio Context audioContext = new (window.AudioContext || window.webkitAudioContext)(); // Connect to WebSocket server const ws = new WebSocket('ws://pc1:8080'); ws.binaryType = 'arraybuffer'; // Setup Media Source Extensions to handle Ogg/Opus stream mediaSource = new MediaSource(); const audioElement = new Audio(); audioElement.src = URL.createObjectURL(mediaSource); audioElement.autoplay = true; mediaSource.addEventListener('sourceopen', () => { const sourceBuffer = mediaSource.addSourceBuffer('audio/ogg; codecs="opus"'); // Append incoming WebSocket data to the source buffer ws.onmessage = (event) => { if (!sourceBuffer.updating && mediaSource.readyState === 'open') { try { sourceBuffer.appendBuffer(event.data); } catch (e) { console.warn('Buffer append error:', e); } } }; ws.onerror = (error) => { console.error('WebSocket connection error:', error); alert('Stream connection failed!'); }; ws.onclose = () => { console.log('Stream disconnected'); mediaSource.endOfStream(); }; }); }); </script> </body> </html>
Save this as ws-stream.html in your /var/www/html directory, then visit http://pc1/ws-stream.html on your phone.
- Make sure your PC and phone are on the same Wi-Fi network
- Open up firewall ports on your PC:
sudo ufw allow 80/tcp sudo ufw allow 8080/tcp - Verify JACK is running:
jackd -d alsa(start JACK if it’s not running) - Check FFmpeg logs for encoding errors—if you see "no such device", double-check your JACK capture device name with
jack_lsp
内容的提问来源于stack exchange,提问作者MadPapo

