среда, 11 сентября 2013 г.

Extract audio with silence from video with ffmpeg

Usually excracting audio track from video file is not a problem and can be done using ffmpeg:
ffmpeg -i video.avi -vn result_audio_track.wav
But if you have video where audio track has silent parts, the command above will extract and concatenate only the parts where audio is not silent. So the result audio track will be shorter than the original. To overcome this the additional parameters should be set:
ffmpeg -i video.avi -vn -af \
    aresample=min_comp=0.001:min_hard_comp=0.100000 \
    result_audio_track.wav
These options prevent ffmpeg from dropping silent parts of audio track:
  • aresample resamples the input audio to the specified parameters.
  • min_comp sets the minimum difference between timestamps and audio data (in seconds) to trigger stretching/squeezing/filling or trimming of the data to make it match the timestamps.
  • min_hard_comp sets the minimum difference between timestamps and audio data (in seconds) to trigger adding/dropping samples to make it match the timestamps.

среда, 28 августа 2013 г.

Multiline regex

The simplest solution would be to use pcregrep, that is grep using the pcre library. Use the flag -M for multiline search:
pcregrep -M 'expression1\nexpression2' filename
if you'd like more 'native' solution without installing additional packages, there's a Python one-liner that will do the job:
alias mlgrep='python -c '\''import re, sys; \
    sys.exit("Usage: mlgrep PATTERN") if len(sys.argv) != 2 else True; \
    match = re.findall(r".*" + sys.argv[1] + r".*", sys.stdin.read().strip(), re.MULTILINE); \
    print("\n".join([x.strip() for x in match])) if match else sys.exit(1)'\'''
add this line to your ~/.bashrc file and use it as:
cat filename | mlgrep "expression1\nexpression2"

среда, 17 июля 2013 г.

Python: set network interface for urllib2

The problem is that urllib2 is based on httplib library which doesn't have such functionality. The best solution I found was this “monkey patch” from Alex Martelli posted on Stack Overflow:
import socket
true_socket = socket.socket
def bound_socket(*a, **k):
    sock = true_socket(*a, **k)
    sock.bind((sourceIP, 0))
    return sock
socket.socket = bound_socket
Simply run this block of code before using urllib2 functions.

пятница, 5 июля 2013 г.

Zabbix + Nginx + PostgresDB

Assuming you already have running nginx and postgres and are going to install Zabbix server. Download and install Zabbix. Then you'll need to install FastCGI for PHP support and several additional packages:
# apt-get install zabbix-server-pgsql zabbix-frontend-php \
    php5-pgsql php5-fpm
You should be prompted to configure postgres database for zabbix during the installation. If not, refer to the documentation on how to do it manually.

Lets proceed to adding PHP support to Nginx for Zabbix. Add the following block to your 'server' in nginx.conf:
location /zabbix {
    if ($scheme ~ ^http:){
        rewrite ^(.*)$  https://$host$1 permanent;
    }
    
    alias               /usr/share;
    index               index.php;
    error_page          403 404 502 503 504  /zabbix/index.php;

    location ~ \.php$ {
        if (!-f $request_filename) { return 404; }
        expires         epoch;
        include         /usr/local/nginx/conf/fastcgi_params;
        fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_index   index.php;
        fastcgi_pass    127.0.0.1:9000;
    }

    location ~ \.(jpg|jpeg|gif|png|ico)$ {
        access_log      off;
        expires         33d;
    }
}
Modify 'include' directive to point to your nginx configuration directory and 'alias' - to zabbix installation dir. Note that if zabbix is installed into
/usr/share/zabbix
set alias to
/usr/share
Now set fastcgi to run on port 9000 and not using socket. Modify
/etc/php5/fpm/pool.d/www.conf
and set:
listen = 127.0.0.1:9000
Now Zabbix page can be opened in your browser: http://<server_ip_or_name>/zabbix. In case it doesn't check all the settings above and nginx and fastcgi logs to fix the problem. Once done proceed with installation steps on the opened page.

четверг, 13 июня 2013 г.

Screencast recording in Linux with ffmpeg

Screencast recording can be performed in HQ using ffmpeg x11grab and pulseaudio:
ffmpeg -f alsa -ac 2 -ab 160k -i pulse -acodec pcm_s16le \
    -f x11grab -r 25 -s 1280x1024 -i :0.0+0,0 -aspect 4:3 \
    -vcodec libx264 -vpre lossless_ultrafast -threads 0 \
    screencast.mkv
options:
-s - recording size
-i - display index + start coords (0,0 - upper left corner)

Run
$ x264 --help
to see all available -vpre options.

ffmpeg should be configured as follows:
./configure --prefix=/usr/local/share/ffmpeg/ --enable-x11grab \
    --enable-gpl --disable-ffplay --disable-ffserver \
    --enable-small --disable-debug --disable-yasm \
    --disable-ffprobe --enable-libx264 --enable-shared

cron + expect + interact

Be careful when you run your shell scripts from cron. cron doesn't have all terminal features. E.g. here's a script that does scp:
 spawn   scp file username@myserver:/home/user
  expect  "*assword: $"
  send    "mystrongpass\n"
  interact 
This example is widely spread. BUT. It won't work from cron. Look at the last directive 'interact'. It returns the process control to the user (there's no user) and redirects stdin and stdout to stdin/stdout of the current process. And it crashes. You should use 'expect' instead:
 spawn   scp file username@myserver:/home/user
  expect  "*assword: $"
  send    "mystrongpass\n"
  expect eof

среда, 12 июня 2013 г.

How to su properly in a shell script & find the original user through multiple sudo commands

When you need to perform several commands from the other user inside a script this will do the job:
#!/bin/bash -
su - user <<HERE
ls -al
# other commands run by 'user'
# ...
HERE
When you need to find out the original owner of the current shell always use
who am i | awk '{print $1}'
or
logname
as no other methods are guaranteed (via stackoverflow).
Another useful tool is environment variable
$SHLVL: Incremented by one each time an instance of bash is started.
It won't show the user but can show the shell 'depth'.

bash ssh hosts auto completion

  1. First of all you should have bash_completion module installed (usually it's installed by default in most Linux-based OS).
  2. Disable host hashing. Set
  3. "HashKnownHosts no"
    in
    /etc/ssh/ssh_config (or ~/.ssh/config just for your profile)
  4. Regenerate known_hosts:
    rm ~/.ssh/known_hosts
Now shell will 'remember' your ssh hosts and allow to use hosts auto completion.