#javascript #airplay
#javascript #трансляция
Вопрос:
Есть ли способ отправлять изображения, видео и аудио на сервер AirPlay, используя JavaScript в браузере?
Комментарии:
1.был ли RAOP, но протокол определенно невозможен только с HTML / JS. Возможно, с помощью некоторых собственных помощников (например, локального сервера).
Ответ №1:
Достичь этого в JavaScript невозможно. Однако вы могли бы запустить его из браузера с помощью плагина NPAPI (с большими трудностями).
Если вы можете запустить локальный сервер, существует несколько node.js модули, которые делают это намного проще. В следующем примере будет транслироваться любой аудиофайл, отправленный на соседнее устройство AirPlay.
- Для этого требуется модуль airtunes из NPM, который я поддерживаю.
- Для перекодирования файла используется FFmpeg.
Вы можете протестировать это с помощью:
curl -X POST --data-binary @sample.mp3 http://localhost:8080/audio
Предполагается, что FFmpeg находится в /usr /local/bin/ ffmpeg, и что устройство AirPlay доступно на localhost: 5000 (вы можете попробовать с Airfoil Speakers).
var airtunes = require('airtunes'),
express = require('express'),
app = express(),
device = airtunes.add('localhost'),
spawn = require('child_process').spawn;
app.post('/audio', function(req, res) {
// use ffmpeg to reencode data on the fly
var ffmpeg = spawn('/usr/local/bin/ffmpeg', [
'-i', 'pipe:0', // Read from stdin
'-f', 's16le', // PCM 16bits, little-endian
'-ar', '44100', // Sampling rate
'-ac', 2, // Stereo
'pipe:1' // Output to stdout
]);
// pipe data to AirTunes
ffmpeg.stdout.pipe(airtunes, { end: false });
// detect if ffmpeg was not spawned correctly
ffmpeg.stderr.setEncoding('utf8');
ffmpeg.stderr.on('data', function(data) {
if(/^execvp()/.test(data)) {
console.log('failed to start ' argv.ffmpeg);
process.exit(1);
}
});
req.pipe(ffmpeg.stdin);
req.on('end', function() {
res.end();
});
});
device.on('status', function(status) {
console.log('status: ' status);
});
console.log('listening on port 8080');
app.listen(8080);
Ответ №2:
У меня это работает
var xhr = new XMLHttpRequest(),
xhr_stop = new XMLHttpRequest(),
hostname = "apple-tv.local",
port =":7000",
position = "0";
xhr_stop.open("POST", "http://" hostname port "/stop", true, "AirPlay", null);
xhr_stop.send(null);
xhr.open("POST", "http://" hostname port "/play", true, "AirPlay", null);
xhr.setRequestHeader("Content-Type", "text/parameters");
xhr.send("Content-Location: " url "nStart-Position: " position "n");
// set timer to prevent playback from aborting
xhr.addEventListener("load", function() {
var timer = setInterval(function() {
var xhr = new XMLHttpRequest(),
// 0 something wrong; 2 ready to play; >2 playing
playback_info_keys_count = 0,
terminate_loop, playback_started;
xhr.open("GET", "http://" hostname port "/playback-info", true, "AirPlay", null);
xhr.addEventListener("load", function() {
playback_info_keys_count = xhr.responseXML.getElementsByTagName("key").length;
console.log("playback: " playback_started "; keys: " playback_info_keys_count)
// if we're getting some actual playback info
if (!playback_started amp;amp; playback_info_keys_count > 2) {
playback_started = true;
console.log("setting playback_started = true")
terminate_loop = false;
}
// playback terminated
if (terminate_loop amp;amp; playback_info_keys_count <= 2) {
console.log("stopping loop amp; setting playback_started = false")
clearInterval(timer);
var xhr_stop = new XMLHttpRequest();
xhr_stop.open("POST", "http://" hostname port "/stop", true, "AirPlay", null);
xhr_stop.send(null);
playback_started = false;
}
// playback stopped, AppleTV is "readyToPlay"
if (playback_started amp;amp; playback_info_keys_count == 2) {
console.log("sending /stop signal, setting playback_started = false")
var xhr_stop = new XMLHttpRequest();
xhr_stop.open("POST", "http://" hostname port "/stop", true, "AirPlay", null);
xhr_stop.send(null);
playback_started = false;
terminate_loop = true;
}
}, false);
xhr.addEventListener("error", function() {
clearInterval(timer);
}, false);
xhr.send(null);
}, 5000);
}, false);