Javascript: трансляция в браузере

#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);