--- title: Raspberry PiでNode.jsを使ってYoutubeストリーミング tags: RaspberryPi Node.js author: PonDad slide: false --- Raspberry Piを手に入れてまず試しにやってみるのは音楽をストリーミング再生させてみることではないでしょうか。(私だけ?) コマンドラインを利用すれば簡単にストリーミングさせることができます。 [コマンドラインからyoutubeを再生する - Qiita](http://qiita.com/tigberd/items/594c27426c5580450bf2) こちらにあるように ```bash:ssh $ youtube-dl 'https://www.youtube.com/watch?v=hoge' -o - | mplayer - ``` 簡単にストリーミング再生出来ます。 ## Node.jsでコマンドライン操作 Node.jsのマニュアル & ドキュメンテーションを見ると ```js:app.js var spawn = require('child_process').spawn, ls = spawn('ls', ['-lh', '/usr']); ls.stdout.on('data', function (data) { console.log('stdout: ' + data); }); ls.stderr.on('data', function (data) { console.log('stderr: ' + data); }); ls.on('close', function (code) { console.log('child process exited with code ' + code); }); ``` こんな風に書いてあります。通常のコマンドはこれでいけるのですが、二つ以上のコマンドを組み合わせようとすると(パイプ)上手くいきません。 ## node.jsでパイプを使ったコマンドを実行するには [node.jsでパイプを使ったコマンドを実行するには - GitHubGist](https://gist.github.com/kjunichi/9439946) こちらのGistを拝見したところ、`sh -c` コマンドを`child_process`で実行して、実際に行いたいコマンドは引数に格納して実行すれば良い様です。 分かった様な、分からない様な。(分ってない)試しに`app.js`をこんな風に書いてみました。 ```js:app.js var spawn = require('child_process').spawn; var cmd = "youtube-dl 'https://www.youtube.com/watch?v=wArJc179HNk' -o - | mplayer - -novideo"; function shspawn(command) { return spawn('sh', ['-c', command]); } var child = shspawn(cmd); var buf=""; child.stdout.on('data',function(data){ buf=buf+data; }); child.stderr.on('data',function (data){ console.log('exec error: '+data); }); child.on('close',function(code) { console.log("exit."); }); ``` 1時間ほどのプレイリスト - [Indie/Indie-Pop Compilation - May 2015 (55-Minute Playlist)](https://www.youtube.com/watch?v=BChec-L3_Xo&ebc=ANyPxKpIBjIEemhBJDFnNed2SC7Oe0NsbGqykAvmOjL83vkx669Xl5KYSw_l9r87XsvVQ2Y3e4MxYL6Z_7SnIIeBrmFXZmZ6xQ) ですが上手くストリーミング再生出来ました。 ## expressを使ってブラウザで操作する `express`を利用して幾つかのプレイリストを操作できる様にしてみました。 ![PonTube Pi 2016-03-02 23-29-46.png](https://qiita-image-store.s3.amazonaws.com/0/47128/5a0f315d-b2e1-b0cd-1ec1-bd3790d2d204.png) ```js:app.js var express = require('express'); var ejs = require("ejs"); var spawn = require('child_process').spawn; var app = express(); app.engine('ejs',ejs.renderFile); app.get('/', function(req, res){ res.render('pontube.ejs', {title: 'PonTube Pi'}); }); app.get('/control', function (req, res) { console.log(req.query); var id = req.query.id; var watch = "https://www.youtube.com/watch?v=" + id; var clear_cmd = "killall mplayer"; //console.log("cmd = "+cmd); function shspawn(command) { return spawn('sh', ['-c', command]); } var child = shspawn(clear_cmd); var buf=""; child.stdout.on('data',function(data){ buf=buf+data; }); child.stderr.on('data',function (data){ //console.log('exec error: '+data); }); child.on('close',function(code) { console.log( 'CLEAR. PLAY.' ); }); var play_cmd = "youtube-dl " + watch + " -o - | mplayer - -novideo"; function shspawn(command) { return spawn('sh', ['-c', command]); } var child = shspawn(play_cmd); var buf=""; child.stdout.on('data',function(data){ buf=buf+data; }); child.stderr.on('data',function (data){ //console.log('exec error: '+data); }); child.on('close',function(code) { console.log( 'EXIT.' ); }); }); app.get('/stop', function (req, res) { console.log(req.query); var id = req.query.id; var stop_cmd = "killall mplayer"; //console.log("cmd = "+cmd); function shspawn(command) { return spawn('sh', ['-c', command]); } var child = shspawn(stop_cmd); var buf=""; child.stdout.on('data',function(data){ buf=buf+data; }); child.stderr.on('data',function (data){ //console.log('exec error: '+data); }); child.on('close',function(code) { console.log( 'STOP.' ); }); }); var server = app.listen(3000, function () { var host = server.address().address var port = server.address().port console.log('This app listening at http://192.168.0.12:'+ port) }); ``` ```html:views/pontube.ejs <%=title %>

<%=title %>

``` コマンドライン操作も良いですが、手元のブラウザから操作出来ると愛着が湧いてきます。 ![DSC_0001.jpg](https://qiita-image-store.s3.amazonaws.com/0/47128/e1e26ff9-3648-8aae-2356-5686ccaed700.jpeg) 音声コマンドと組み合わせても面白いかもしれません。では。