29

I know I can just do mplayer <stream> to open and play a stream on the local machine. However, I'm behind a firewall.

Instead, I'd like to open the stream on a remote machine, but still play it on this one. Remote connections are what SSH is for, but doing ssh "mplayer <stream>" both opens and plays the stream on the remote.

SSH's -x flag enables X11 display forwarding. Do I need that?

Anko
  • 4,526

4 Answers4

34

You can use wget over ssh to open an HTTP connection and output stream data, then mplayer on the local machine to play it.

ssh <user>@<host> "wget <stream> -O -" | mplayer -cache 512 -

The subtleties:

  • wget's -O (capital letter oh) option sets its output file; - (dash) implies stdout.

  • mplayer's -cache option causes a configurable amount of input to be buffered, compensating for network jitter. The - (dash) option makes it read from stdin.

Try streaming SceneSat Radio, for example. http://r1.scenesat.com:8000/scenesat

Anko
  • 4,526
  • 6
    I don't even know what kind of music this is, but because I'm piping it, it's awesome! Thanks. – SaultDon Nov 12 '13 at 19:58
  • 1
    Note that the question doesn't mention any particular protocol over which music is streamed. There are other protocols over which music can be streamed, for example RTP and MMS. Both can be played by mplayer, but not downloaded by wget. – liori Nov 13 '13 at 22:44
  • @liori Good point. This clearly isn't a general solution. – Anko Nov 13 '13 at 23:41
19

You can use ssh's -L flag to create a tunnel from your system to a remote:

ssh -L <localport>:<streamhost>:<streamport> <user>@<remote>

You can then connect to your end of the tunnel with mplayer as you would otherwise:

mplayer localhost:<localport>
Anko
  • 4,526
  • 1
    Note that this will not work if the HTTP server is using virtual domains (or in other words, requires a proper domain name sent by the client as an HTTP header). To solve this problem, you can for example temporarily add a rule to your hosts file that will make mplayer think that the target domain is hosted at local machine. – liori Nov 13 '13 at 22:47
  • 3
    Or you could use -http-header-fields to force a Host header. – Ignacio Vazquez-Abrams Nov 13 '13 at 22:55
  • @IgnacioVazquez-Abrams do you mind clarifying where? I don't such an option in man ssh. – William Nov 14 '13 at 04:17
  • @LiamWilliam: It's a mplayer option. – Ignacio Vazquez-Abrams Nov 14 '13 at 04:32
8

You can set up a SOCKS proxy:

ssh -D localhost:8080 user@remotehost
mplayer http_proxy://localhost:8080/http://stream

You can use tell any other application, such as your web browser, to use this proxy too.

ssch
  • 241
  • 2
    Does the http_proxy feature actually work with SOCKS proxies too? The feature is undocumented in my man page, and various sites on the web prefer the tsocks approach. – liori Nov 13 '13 at 23:05
  • 1
    @liori: Yes, this works together with tsocks mplayer -playlist http://bassdrive.com/bassdrive.m3u. Thanks for your advise. Without tsocks (aka only with http_proxy://…) it didn’t work. – erik May 06 '16 at 16:10
6

sshfs is a wonderful tool for cases like this. It hides many a firewall and allows you to use whatever player you choose (though mplayer is still a nice choice).

sudo apt-get install sshfs # your favorite packager here
sshfs me@mydomain.org:/home/arthur/Music ~/Music

I also run Subsonic listening to port 4040 on localhost and then ssh-tunnel home with

ssh -L 4040:localhost:4040 me@mydomain.com

I can then open Subsonic in the browser at http://localhost:4040.

Anko
  • 4,526