Thursday, September 26, 2013

Extract audio track from a youtube video

Youtube is a great source for watching videos or listening to music on-line via their website. But if you want to download the video or audio to your computer, you need some special tool, and you need to know the URL for the youtube video you wish to download.

One such tool is youtube-dl, which is a python script. Unfortunately, youtube-dl is not pre-packaged with Debian Wheezy.

I downloaded the script directly from this web page:

$ sudo curl https://yt-dl.org/downloads/2013.09.24.2/youtube-dl -o /usr/local/bin/youtube-dl
$ sudo chmod a+x /usr/local/bin/youtube-dl

The syntax of youtube-dl is quite straight-forward.

To download the complete youtube video (with the soundtrack), just provide the URL of the video as a single argument.

$ youtube-dl http://www.youtube.com/watch?v=O-xlvalecI8 
[youtube] Setting language
[youtube] O-xlvalecI8: Downloading video webpage
[youtube] O-xlvalecI8: Downloading video info webpage
[youtube] O-xlvalecI8: Extracting video information
[youtube] O-xlvalecI8: Encrypted signatures detected.
[youtube] O-xlvalecI8: Downloading js player vflUKrNpT
[download] Destination: Give me oil in my lamp-O-xlvalecI8.flv
[download] 100% of 11.73MiB in 00:43

This creates a Flash Video (.flv) file in your local hard drive. To watch the video off-line, open the .flv file with a media player application such as VLC or Totem.

If it is just the sound track that you want, not the complete video, you can still use youtube-dl. However, to do audio extraction, youtube-dl requires 2 extra programs to be installed. Namely, it requires ffmpeg or avconv, and ffprobe or avprobe.

On my Debian Wheezy system, I installed avconv and avprobe by simply installing this package:

$ apt-get install libav-tools

Finally, you can run youtube-dl like this to extract the audio track only:

$ youtube-dl --extract-audio --audio-format mp3   http://www.youtube.com/watch?v=O-xlvalecI8 
[youtube] Setting language
[youtube] O-xlvalecI8: Downloading video webpage
[youtube] O-xlvalecI8: Downloading video info webpage
[youtube] O-xlvalecI8: Extracting video information
[download] Destination: Give me oil in my lamp-O-xlvalecI8.flv
[download] 100% of 11.73MiB in 00:32
[avconv] Destination: Give me oil in my lamp-O-xlvalecI8.mp3
Deleting original file Give me oil in my lamp-O-xlvalecI8.flv (pass -k to keep)
The --audio-format parameter lets you specify the output audio format. The above command generates a mp3 file on your local hard drive. Besides mp3, you can specify other audio formats such as wav. For detailed help about the parameters, run:
$ youtube-dl --help

Monday, May 20, 2013

X11 Forwarding over SSH: run remote graphical app and display locally

In the modern networked environment, we often wish to run an application on a remote host while we are comfortably logged in on our local computer.

Assuming both machines are Linux-based, and the application runs on the graphical X desktop, the following approaches come to mind:

  • VNC
  • X11 forwarding over SSH

This article focuses only on X11 forwarding. X11 forwarding over SSH enables you to run a remote X app and display it locally, with traffic between the 2 hosts encrypted by SSH.

For X11 forwarding over SSH to work, both the SSH client and SSH server must be properly configured.

X11 forwarding must be enabled on The SSH server side. This is the machine where the application resides. To enable the feature, make sure the X11 configuration file /etc/ssh/sshd_config on the server contains this line:

X11Forwarding yes

If you edit the said file, you need to restart the sshd daemon for the change to take effect.

On Debian or Ubuntu systems, you restart the SSH daemon like this:

$ sudo service ssh restart
[ ok ] Restarting OpenBSD Secure Shell server: sshd.
$

On the ssh client side, you need to run SSH command with the proper parameters. For instance, suppose you want to run the xclock application on the remote SSH server and have it displayed back on the local client.

$ ssh -fX peter@192.168.1.112 xclock 
peter@192.168.1.112's password: 
$

The -X parameter allows an one-off X11 forwarding session.

The -f parameter instructs the SSH client to go to the background just before xclock is run.

If you want to permanently enable X11 forwarding for an user, insert this line in the user's own ~/.ssh/config file on the local host.

ForwardX11 yes 

With X11 forwarding permanently enabled for the client, you can leave out the -X parameter:

$ ssh -f peter@192.168.1.112 xclock 
peter@192.168.1.112's password: 
$

If X11 forwarding is not enabled on the SSH server, any attempt to tunnel X11 will fail with the following error message:

$ ssh -X peter@192.168.1.112 xclock 
peter@192.168.1.112's password: 
X11 forwarding request failed on channel 0
Error: Can't open display: 
$
If X11 forwarding is properly enabled on the server side, you will see a nice looking clock displayed on your local screen.

Thursday, May 2, 2013

Forcing pseudo terminal on ssh command execution

You already know how to execute a command on a remote computer via ssh.

The syntax is like this:

$ ssh peter@192.168.1.112 

This will work if the command is simply piping output, for example, ls.

If the command is "screen-based" in that it interprets user input, you may get an error. The following shows what happens when you ssh to run such programs (e.g., top, emacs, screen).

$ ssh peter@192.168.1.112 top
peter@192.168.1.112's password: 
TERM environment variable not set.
$ ssh peter@192.168.1.112 emacs
peter@192.168.1.112's password: 
emacs: standard input is not a tty
$ ssh peter@192.168.1.112 screen
peter@192.168.1.112's password: 
Must be connected to a terminal.

Here is a high-level explanation of what is happening behind the scene.

When you run ssh without a command just to login, a pseudo tty is automatically allocated. But if you specify a command to execute on the ssh command line, by default, ssh does not allocate a pseudo tty. You need to force it to allocate one if you want to run commands such as top or screen. This you do by giving the -t parameter to ssh.

$ ssh -t peter@192.168.1.112 top
peter@192.168.1.112's password: 
top - 11:09:46 up 133 days, 13:44,  5 users,  load average: 0.00, 0.00, 0.00
Tasks: 201 total,   1 running, 200 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.2%sy,  0.0%ni, 99.8%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1938896k total,  1466144k used,   472752k free,   592508k buffers
Swap:        0k total,        0k used,        0k free,   508120k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
22176 peter     20   0  2856 1296  984 R  0.3  0.1   0:00.07 top
    1 root      20   0  3944  572  332 S  0.0  0.0   0:02.80 init
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.17 kthreadd
    3 root      RT   0     0    0    0 S  0.0  0.0   0:09.22 migration/0
    4 root      20   0     0    0    0 S  0.0  0.0 406:20.92 ksoftirqd/0
    5 root      RT   0     0    0    0 S  0.0  0.0   0:00.03 migration/0

In summary, if you run ssh with a command argument to execute on a remote server, and you see an error message that suggests a terminal is not configured, run it again with the -t parameter.

Monday, April 22, 2013

One-liner to shutdown remote host

To shutdown the local machine immediately, you execute this command as root or under sudo:
$ shutdown -h now

If it is a remote server that you want to shutdown, it could be slightly more involved.

You need to have root privileges to shutdown a machine. However, many systems are configured to block root from logging in remotely usingssh. So, you need to ssh in as a regular, non-root user, and pass the sudo command to shutdown host.

$ ssh -t peter@192.168.1.112 'sudo shutdown -h now'
peter@192.168.1.112's password: 
[sudo] password for peter: 
Broadcast message from root@tiger (pts/2) (Sat Apr 13 10:56:30 2013):

The system is going down for system halt NOW!
Connection to 192.168.1.112 closed.
$ 

Don't forget the -t sshparameter to "force pseudo-tty allocation". Without it, the above one-liner will fail with this message.

sudo: no tty present and no askpass program specified

Note that you will be prompted twice to type in your password. The first time is for ssh; the second, sudo.

To avoid typing the first password, set up password-less login. This is a topic by itself, and I won't go into it here.

To avoid the second, configure sudo to not prompt peter for his password when he issues a sudo command. This is done by editing the /etc/sudoers file.

$ visudo

Insert the following line to the file:

peter ALL=(ALL) NOPASSWD: ALL

The above line allows peter to sudo as anybody from any host and run any command without being authenticated. Only do this after you have considered its security ramifications. You have been forewarned.

Now run the one-liner again.

$ ssh -t peter@192.168.1.112 'sudo shutdown -h now'
peter@192.168.1.112's password: 

Broadcast message from root@tiger (pts/1) (Sat Apr 20 21:40:50 2013):

The system is going down for system halt NOW!
Connection to 192.168.1.112 closed.
The user is only prompted once, by ssh, to enter a password.

Friday, April 19, 2013

One-liner to copy text to a remote host

Occasionally, I want to copy a short line of text to a remote computer. For instance, I have an URL for some real cool web site which, for whatever reason, I want to send to a remote host. I can always put the text in a file, and transfer it via scp.

$ cat > coolurl.txt
http://really-cool-web-site/

$ scp coolurl.txt peter@192.168.1.112:

Or, you can use the following one-liner command:

$ echo 'http://really-cool-web-site/'|ssh peter@192.168.1.112 'cat >coolurl.txt'

The one-liner uses only simple commands such as echo, ssh and cat. It saves you the step of creating a new file on the local machine.

The text is saved to a file called coolurl.txt on the remote computer under your home directory.

Let me know your favourite way to accomplish the same thing.