Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audio streaming only (feature request) #3704

Open
Joci78 opened this issue Apr 18, 2024 · 2 comments
Open

Audio streaming only (feature request) #3704

Joci78 opened this issue Apr 18, 2024 · 2 comments

Comments

@Joci78
Copy link

Joci78 commented Apr 18, 2024

Share your bug report, feature request, or comment.

Dear Dev,

Is it possible to develop an option where only audio can be streamed?

@gabek
Copy link
Member

gabek commented Apr 18, 2024

As it is currently built, this is not possible. Many changes would have to be made to the video pipeline to have something like that work. If you're looking for something that legitimately only streams audio, I recommend Icecast, as that is built for that purpose.

@wKoja
Copy link

wKoja commented Apr 27, 2024

Not sure if this is gonna help you, but maybe other people want the same thing, so in the hopes that this is useful to you or someone in the future, I'll post this here:

My workaround to this was setting up an nginx server, with the nginx-rtmp-module, ffmpeg and Caddy to serve an audio only stream.

The command below feeds off the original stream, strips the video, then pipes the audio to nginx:

ffmpeg -i http://video.mydomain.tv/hls/stream.m3u8 -c:a copy -vn -f flv rtmp://localhost:1935/live/

Here's the nginx config:

worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

# nginx default 
events {
  worker_connections 768;
}

rtmp {
  server {
    listen 1935; # RTMP port
    chunk_size 4096;
    application live {
      live on;
      record off; # only creates ephemeral files, old chunks will be deleted right away
      hls on;
      hls_path /var/www/html/stream/hls; # create this dir and make sure it's writable
      hls_fragment 5s;
      hls_playlist_length 30s;
    }
  }
}

http {
  server {
    listen 9090;
    location /hls {
      root /var/www/html/stream;
      add_header Cache-Control no-cache;
      add_header Access-Control-Allow-Origin *; # or restrict this to only  be accessible from your website
    }
  }

# rest of your config, if any
}

You can then configure nginx to expose it to the web, which is a bit complicated, especially with SSL, or simply set up a Caddy server in front of it, which is what I did. Assuming you'll already have your audio domain set up as audio.mydomain.tv somewhere (e.g Cloudflare)

Caddyfile (usually under /etc/caddy/Caddyfile):

audio.mydomain.tv {
  reverse_proxy /hls/* localhost:9090 # nginx server
  encode gzip
  tls your@email.com
}

Ideally, you'll have some mechanism in place to start the audio stream the moment its related Owncast stream starts.
This can be done by combining Owncast's webhook feature and a middleware service capable of performing HTTP requests. Below is how I've done it:

Copy the ffmpeg command in a start_stream.sh script and set up a Caddy endpoint with the exec plugin so you can programmatically start a stream.

Updated Caddyfile with a /start endpoint:

audio.mydomain.tv {
  reverse_proxy /hls/* localhost:9090
  encode gzip
  tls your@email.com
 
  @not-options not method OPTIONS # so your server doesn't get 401'd, don't ask me why this happens
  route /start {
    basicauth {
      user {ecrypted-password} # read more https://caddyserver.com/docs/caddyfile/directives/basicauth
    }
    exec {
      command /path/to/start_stream.sh
      timeout 10s
    }
  }
}

Now using Owncast's webhook feature, you'll be able to start the audio stream from a middleware service. In my case, we already have a nodejs server up and running. It made sense to just add another endpoint for this purpose.

Here's the nodejs snippet, using express.js and axios to perform HTTPS requests:

//LiveStreamController.js

const startAudioStream = async (request, response) => {
  // incoming Owncast webhook notification
  const payload = request.body;

  try {
    const type = payload.type;

    const { CADDY_SECRET } = process.env; //already generated secret from btoa(`${user}:${password}`)

    const headers = {
      'Authorization': `Basic ${CADDY_SECRET}`,
      "Content-Type": "application/json",
    };

    if (type === "STREAM_STARTED") {
      await delay(5000) // Wait 5 seconds. Can't start audio stream right away, gotta wait for a bit
      await axios.get("https://audio.mydomain.tv/start", {
        headers,
      });
    }
  } catch (error) {
    return response.status(500).json({ message: "Something happened" });
  }

  return response.status(200).json({ message: "Success" });
};

Now when the stream starts, Owncast will fire a START_STREAM notification to your webhook, and it'll be able to start an audio stream in your ffmpeg/nginx/caddy server.

If you don't have a server ready to use as middleware for any reason and don't want to set up one, you can get away with simply having a curl command ready, or even a Postman or Insomnia request to start the audio stream right after starting your original stream.

You don't need to set up a STOP_STREAM notification, because once the original stream stops and the feed dies, ffmpeg will stop automatically a few moments later.

With this set up, your audio stream will be available at https://audio.mydomain.tv/hls/stream.m3u8.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants