3

I am trying to stream just audio from a youtube link straight to http with node.js.

My code looks like this, I am using express 4.0.

var express = require('express');
var router = express.Router();
var ytdl = require('ytdl');
var ffmpeg = require('fluent-ffmpeg');
var fs = require('fs');

router.get('/', function(req, res) {

  var url = 'https://www.youtube.com/watch?v=GgcHlZsOgQo';
  var video = ytdl(url)

  res.set({
      "Content-Type": "audio/mpeg"
  })

  new ffmpeg({source: video})
      .toFormat('mp3')
      .writeToStream(res, function(data, err) {
        if (err) console.log(err)
      })

});

module.exports = router;

Now, I'm able to stream the video's audio to the response if I save the file then pipe it to the response, but I'd rather try to figure out some way to go from downloading to ffmpeg to response.

Not sure if this is possible. The main goal is to keep it as light weight as possible, and not have to read from files.

I've seen this code which is essentially what I'd like to do minus the saving to a file part.

part of the error

user2758113
  • 1,001
  • 1
  • 13
  • 25
  • This is entirely possible. What about your code isn't working? I'm not familiar with `ytdl` and `fluent-ffmpeg`, but I've done similar things by just running FFmpeg as a child process and piping the result right to the response. Some things to consider... your server will buffer in memory if the client is slower than what you're getting out of FFmpeg. Be prepared to use a ton of memory for a server like this. You might consider a large swapfile. Also, what you're doing violates the YouTube terms of service. – Brad Apr 27 '14 at 23:59
  • The error I'm getting is just an empty response, and the stream is closing right when I make the request. – user2758113 Apr 28 '14 at 00:04
  • Im going to look into ffmpeg child processes though, thanks. – user2758113 Apr 28 '14 at 00:05
  • Don't test with Chrome. It makes multiple requests as it tries to figure out what to do with your media, and whether or not it supports seeking. First, make sure you can write to a file. Next, make sure you can use curl or wget with your server. Then test with a normal client like VLC. Then, figure out how to handle Chrome. (And, requests from clients like Chrome are why your approach may not be the best. Are you site you don't want to at least cache on disk for awhile?) – Brad Apr 28 '14 at 00:19
  • Can write to file. Curl is working, getting data back. Utimately Im going to use this as a little api, so not working in chrome is okay. – user2758113 Apr 28 '14 at 00:27
  • maybe fluent doesn't support live streaming? – rogerdpack Apr 28 '14 at 16:02
  • Was this ever accomplished? – Majster Jul 20 '15 at 19:25

1 Answers1

1

Since, res is a stream and ffmpeg is also a stream.
We pipe them each other with .pipe().


Stream data with pipes

Using pipe(s) doesn't require to save files in ROM. The data is stored in RAM and accessed when needed. It's very efficient way to stream files!

router.get('/', function(req, res) {
  var url = 'https://www.youtube.com/watch?v=GgcHlZsOgQo';

  // Audio format header (OPTIONAL)
  res.set({ "Content-Type": "audio/mpeg" });

  // Send compressed audio mp3 data
  ffmpeg()
  .input(ytdl(url))
  .toFormat('mp3')
  .pipe(res);
});