Генератор кредитных карт онлайн (с исходниками)

Генератор кредитных карт (Credit Card Test Numbers) может быть полезен для разработчиков, тестирующих сайты электронной коммерции. Сгенерированные карты удовлетворяют алгоритму Luhn, но не являются действительными. На этапе оплаты при их использовании в вашем магазине должен произойти отказ. Срок годности карты может быть установлен любым (в пределах 3х ближайших лет).

Генератор кредитных карт в действии:
[executecardsscript]

Исходники (GPL) на Python, Java, C#, PHP и Javascript: zip, tar.gz

Credits: Graham King

Google переворачивается при наборе “do a barrel roll”

Попробуйте перейти на главную страницу Google, в строке поиска ввести “do a barrel roll” и нажать enter. Вы увидите следующее:

Представленный очередной прикол от Google, демонстрирующий всю мощь CSS3, был создан software-инженером Google для развлечения пользователей. Прикол, как говорит Google, не работает в старых браузерах, не поддерживающих HTML5.

В twitter поступает много сообщений от пользователей, открывших для себя прикол “Do a barrel roll“:

> Google search “Do A Barrel Roll.” Right now.

> GOOGLE TRICKS: →type in “do a barrel roll” and hit enter, the screen should spin. (:

> Quick! Do a backflip! Actually, do a barrel roll!

Также при наборе слова “tilt” Google наклоняется!

При наборе “zerg rush” поисковую выдачу поедают буквы OOO из Gooooogle.

Весь список “пасхальных яиц” Google на Wiki:

List of Google’s hoaxes and easter eggs

How to make Wikipedia work #wikipediablackout

The Wikipedia community has blacked out the English version of Wikipedia for 24 hours to raise awareness about legislation being proposed by the U.S. Congress — the Stop Online Piracy Act (SOPA) in the U.S. House of Representatives, and the PROTECT IP Act (PIPA) in the U.S. Senate — and to encourage readers to speak out against it.

What should we do if we want knowledge? Just do the following to view Wikipedia normally:

  1. Open the desired link
  2. Wait some time (about a second or two, depends on your Internet connection speed)
  3. Just press the ESCAPE button to avoid redirect to the black page

[youtube=http://www.youtube.com/watch?v=1zmwL-09aVM&w=320&h=240]

[youtube=http://www.youtube.com/watch?v=C73iKkkreWs&w=320&h=240]

The English Wikipedia will be accessible on mobile devices and smart phones. Because the protest message is powered by JavaScript, it’s also possible to view Wikipedia by completely disabling JavaScript in your browser.

Enjoy Wikipedia and support the blackout!
I support #wikipediablackout! Show your support here http://tinyurl.com/7vq4o8g

Thanks

How do geeks shop? (Inspired by Stanford DB-Class)

Recently online shopping has become especially popular, superseding and leaving far behind its competitors who work in usual shops. It’s quite convenient, online shops are open 24h without breaks and days-off!

Sometimes I buy goods from StrawberryNET.Com for my wife and myself. Unfortunately, there is a huge problem with the seller’s website. Its interface doesn’t provide customers the ability to sort goods by price, discounts, etc. I don’t know if it is made for special reason or it’s just some human laziness, but it’s none of my business. The geek can get everything he wants from the site.

This year I am taking Stanford’s online class launched this fall by Jennifer Widom: Introduction to Databases. I like the course very much and the author of the course as well! Inspired by db-class I implemented the website’s missing sort feature and was able to sort goods as much as I wished.

To implement the feature I used SQL and sed on my Ubuntu Linux 11.10 oneiric ocelot. First of all I parsed the site’s data and received it in this form (data.txt file):

Ermenegildo Zegna - Z Zegna
Z Zegna Deodorant Stick 75g/2.5oz
Price: US$ 18.50 - (Save 8%)
Giorgio Armani - Acqua Di Gio
Acqua Di Gio Deodorant Stick 75g
Price: US$ 29.00
Joop - Joop Thrill
Joop Thrill For Him Deodorant Stick 70g
Price: US$ 13.00 - (Save 50%)
Paco Rabanne - Paco Rabanne Pour Homme
Pour Homme Deodorant Stick 75ml/2.2oz
Price: US$ 21.50 - (Save 2%)
Bvlgari - Aqva Pour Homme Marine
Aqva Pour Homme Marine Deo Stick 75g/2.7oz
Price: US$ 16.50 - (Save 41%)
Ralph Lauren - Polo Blue
Polo Blue Deodorant Stick 75g/2.5oz
Price: US$ 29.00
Hugo Boss - Hugo
Hugo Deodorant Stick 70g/2.4oz
Price: US$ 26.50
Loris Azzaro - Azzaro Elixir
Azzaro Elixir Coffret: Eau De Toilette Spray 100ml/3.3oz + Deodorant Stick 75g/2.5oz 2pcs
Price: US$ 42.50 - (Save 50%)

Then I designed my SQL database:

drop table if exists Strawberry;
create table Strawberry(brand text, series text, title text, price real, save int);
select * from Strawberry;

Using sed I converted the parsed data to SQL insert queries. sed script (sed.sed file):

1~3 s/ - /","/
1~3 s/^/INSERT INTO Strawberry VALUES ("/
1~3 s/$/"/
2~3 s/^/"/
2~3 s/$/"/
3~3 s/Price: US$ //
3~3 s/$/,0);/
3~3 s/ - (Save /,/
3~3 s/%),0//
3~3 s/%)\ ,0//

The script is ready to be executed by this bash command:

sed -f sed.sed data.txt | sed -e ':a;N;$!ba;s/"\n/",/g' | xclip

xclip is a nice tool to output data to directly to OS clipboard.

The data I got using sed script:

INSERT INTO Strawberry VALUES ("Ermenegildo Zegna","Z Zegna","Z Zegna Deodorant Stick 75g/2.5oz",18.50,8);
INSERT INTO Strawberry VALUES ("Giorgio Armani","Acqua Di Gio","Acqua Di Gio Deodorant Stick 75g",29.00,0);
INSERT INTO Strawberry VALUES ("Joop","Joop Thrill","Joop Thrill For Him Deodorant Stick 70g",13.00,50);
INSERT INTO Strawberry VALUES ("Paco Rabanne","Paco Rabanne Pour Homme","Pour Homme Deodorant Stick 75ml/2.2oz",21.50,2);
INSERT INTO Strawberry VALUES ("Bvlgari","Aqva Pour Homme Marine","Aqva Pour Homme Marine Deo Stick 75g/2.7oz",16.50,41);
INSERT INTO Strawberry VALUES ("Ralph Lauren","Polo Blue","Polo Blue Deodorant Stick 75g/2.5oz",29.00,0);
INSERT INTO Strawberry VALUES ("Hugo Boss","Hugo","Hugo Deodorant Stick 70g/2.4oz",26.50,0);
INSERT INTO Strawberry VALUES ("Loris Azzaro","Azzaro Elixir","Azzaro Elixir Coffret: Eau De Toilette Spray 100ml/3.3oz + Deodorant Stick 75g/2.5oz 2pcs",42.50,50);

Using the database I was able to construct as much SQL-queries as I wished, to sort goods of my favorite brands using SELECT, SORT, ORDER and other SQL structures.

The profit I received:

  • saved some money buying the goods
  • saved some time (it’s easier to manage DB than to use that site)
  • the most important: put into practice the knowledge I gained after listening the db-class Stanford course!

Many thanks to Stanford Engineering and Prof. Jennifer Widom.

Разделение страниц пополам в DJVU с помощью ImageMagick

Bash script:

#!/bin/bash
#sudo apt-get install djvulibre-bin imagemagick libtiff-tools
#rm *.tif
for (( i=0; i<=317; i++ ))
        do ddjvu -page=$i -format=tiff assimil_france.djvu tmp$i.tif
        convert tmp$i.tif -crop 50%x100% $i%d.tif
        rm tmp$i.tif
done
for a in [0-9]*.tif; do
    mv $a "printf %05d.%s ${a%.*} ${a##*.}"
done
tiffcp *.tif out.tif && tiff2pdf out.tif -j -o out.pdf && rm *.tif

FFmpeg: Объединение нескольких avi файлов

Некоторые мультимедиа контейнеры (MPEG-1, MPEG-2 PS, DV) позволяют объединять несколько видеофайлов обыкновенной конкатенацией.

Таким образом, объединить мультимедиа файлы можно с помощью первичного транскодирования видео в привеллигированные форматы, затем используя команду cat (или copy в Windows) и конечного транскодирования видеоматериалов в любой формат на ваш выбор.

ffmpeg -i input1.avi -sameq intermediate1.mpg
ffmpeg -i input2.avi -sameq intermediate2.mpg
cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg
ffmpeg -i intermediate_all.mpg -sameq output.avi

Команда -sameq позволяет сохранять битрейт в процессе обработки для исключения деградации качества видео.

Также, использование pipes в вашей операционной системе позволяет избежать создание промежуточных файлов:

mkfifo intermediate1.mpg
mkfifo intermediate2.mpg
ffmpeg -i input1.avi -sameq -y intermediate1.mpg < /dev/null &
ffmpeg -i input2.avi -sameq -y intermediate2.mpg < /dev/null &
cat intermediate1.mpg intermediate2.mpg |\
ffmpeg -f mpeg -i - -sameq -vcodec mpeg4 -acodec libmp3lame output.avi

Источник: FAQ по FFmpeg

Кнопки “P” и “W” на клавиатуре телефона

В современных телефонах на клавиатуре при наборе номера есть такие символы как P и W. В моём HTC Desire для их набора необходимо несколько раз быстро нажать звёздочку “*”.

Предназначены они для эффективного работы с автоматическими голосовыми меню (IVR).

Кнопка “P” (pause) даёт команду телефону ждать небольшое количество времени, затем продолжить набор номера. Кнопка “W” (wait) означает ждать взаимодействия от пользователя (по нажатию кнопки набор продолжится).

Очень удобно звонить с помощью этих кнопок через IP телефонию.
Набор номера в таком случае может быть таким:

+XXXXXXpYYYYYY

Где XXXXXX – номер провайдера IP-телефонии, а YYYYYY – сам номер абонента.

Запоминание позиции воспроизведения файла в MPlayer

Понравилась статья, оригинал тут.
Спасибо автору, давно искал. Mplayer Tools компилил, не понравлось.
От себя добавлю: хотел пользоваться этим вместе с gnome-mplayer, но он, к сожалению, не знает параметр -ss и не может стартовать с заданного времени.

Думаю, многим знакома следующая ситуация. Вы запускаете свой любимый MPlayer, чтобы посмотреть какой-нибудь фильм, смотрите, но до конца досмотреть не успеваете, т. к. вам нужно куда-нибудь уходить. Вы закрываете MPlayer, выключаете компьютер и идете по своим делам. Вернувшись, вы
решаете досмотреть фильм. Вот только где же вы остановились? Что делать? «Проматывать», пока не наткнетесь на тот момент, который не видели?

Записывать время остановки на бумажке? 🙂 Нет, это не наш метод…

Когда я в очередной раз столкнулся с этой проблемой, то пошел на домашнюю страницу MPlayer, на которой нашел два скрипта для ее решения: mplayer-resume и MPlayer Tools.

mplayer-resume у меня отказался запоминать позиции в файлах и к тому же подавлял весь вывод mplayer’a, что довольно неаккуратно с его стороны, так что я сразу же отказался от него, а MPlayer Tools показался мне слишком неудобным в использовании. Поэтому я решил изобрести собственный велосипед. 🙂

В итоге на свет появился относительно небольшой скрипт, представленный ниже. Скрипт полностью сохраняет вывод MPlayer’a и может принимать все аргументы, которые принимает MPlayer. В том числе ему можно передавать одновременно несколько файлов для воспроизведения — каждый из них он
воспроизведет с того места, на котором было остановлено воспроизведение в прошлый раз.

Краткое описание можно прочитать в комментариях, располагающихся в начале самого скрипта.

Удачи, надеюсь, скрипт окажется вам полезен и сэкономит хотя бы немного вашего времени и нервов. 🙂

#!/bin/bash
#***************************************************************************
#*   Copyright © 2008, Konishchev Dmitry                                 *
#*   http://konishchevdmitry.blogspot.com/                                 *
#*                                                                         *
#*   Project homepage:                                                     *
#*   http://sourceforge.net/projects/mplayerext/                           *
#*                                                                         *
#*   This program is free software; you can redistribute it and/or modify  *
#*   it under the terms of the GNU General Public License as published by  *
#*   the Free Software Foundation; either version 3 of the License, or     *
#*   (at your option) any later version.                                   *
#*                                                                         *
#*   This program is distributed in the hope that it will be useful,       *
#*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
#*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
#*   GNU General Public License for more details.                          *
#**************************************************************************/

# mplayer.ext - скрипт-оболочка для mplayer.
# 
# Предназначен для продолжения прослушивания/просмотра аудио и видео
# файлов с той позиции, на которой просмотр/прослушивание завершился в
# прошлый раз при закрытии mplayer'a.
# 
# Использование:
# Если вы хотите пользоваться возможностями скрипта, вам необходимо
# всегда, когда вы хотите проиграть аудио/видео файл, вызывать этот скрипт
# вместо mplayer'a.
# 
# Как работает скрипт:
# Если завершение работы mplayer'a происходит во время просмотра фильма,
# то в файл, путь к которому задан переменной $resume_info_file, заносится
# информация о времени, на котором произошло прерывание просмотра. Время
# привязывается к имени файла (имени, а не пути!), таким образом, если файл
# будет перемещен в другую дирректорию, то скрипт все равно его "узнает".
# В следующий раз, когда пользователь запросит проигрывание этого фильма,
# скрипт просмотрит файл, заданный переменной $resume_info_file и
# продолжит воспроизведение фильма с того момента, на котором завершилось
# воспроизведение в прошлый раз.
# 
# Максимальное количество файлов, информация о которых может храниться в
# $resume_info_file задается переменной $max_resume_info_length.
# 
# Ограничения скрипта:
# * Скрипт не обрабатывает файлы DVD вида VTS_*_*.VOB, т. к. mplayer не
#   позволяет начинать воспроизведение таких файлов с произвольного места.
# * Т. к. mplayer позволяет начинать воспроизведение фильма только с
#   ключевого кадра, то, если воспроизведение фильма в прошлый раз
#   прервалось не на ключевом кадре, при попытке воспроизвести фильм с
#   того же места произойдет перемотка вперед до следующего ключевого
#   кадра, т. е. часть фильма останется непросмотренной. В связи с этим
#   скрипт производит "отматывание" на $keyint секунд назад (по умолчанию
#   - 10), т. к., при кодировании большинства MPEG-4 файлов данная
#   величина используется в качестве максимального расстояния между
#   ключевыми кадрами. Если в ваших видеофайлах интервал между ключевыми
#   кадрами больше этого значения, то измените значение переменной $keyint.  

# Настойки -->
        # Максимальный интервал между ключевыми кадрами
        keyint=10

        # Файл, в котором будет храниться информация о недосмотренных файлах
        resume_info_file=~/.mplayer/resume_info

        # Максимальное количесво файлов, информация о которых будет храниться в $resume_info_file
        max_resume_info_length=100
# Настойки <--

mplayer_ext_echo()
{
        echo "mplayer.ext: $@"
}

mplayer_ext_warning()
{
        mplayer_ext_echo "$@" >&2
}

cleanup()
{
        rm -f $tmp_file
}

die()
{
        mplayer_ext_warning "$@"
        cleanup
        exit 1
}

# Возвращает идентификатор видео по имени файла
get_video_name_by_file_name()
{
        local video_name=$(basename "$1")

        if [[ "$video_name" == "" ]]
        then
                return 1
        fi

        # Не обрабатываем файлы DVD, т. к. в них невозможно осуществлять воспроизведение
        # с произвольного места
        if echo -n "$video_name" | egrep -i '^vts_[[:digit:]]+_[[:digit:]]+.vob$' > /dev/null
        then
                return 1
        fi

        echo -n "$video_name"
}

# Если $2 == 0, то файл помечается как просмотренный
set_resume_pos()
{
        declare -a resume_info_array
        local resume_info resume_info_time resume_info_time i

        # Устанавливаем разделитель слов равным \n
        local IFS=$'\n'

        i=0
        for resume_info in `cat "$resume_info_file" | tail --lines $((max_resume_info_length - 1))`
        do
                resume_info_time=`echo -n "$resume_info" | egrep '^.+:[[:digit:]]+$' | sed -r 's/^.+://' | egrep '^[[:digit:]]+$'`
                resume_info_name=`echo -n "$resume_info" | sed "s/:${resume_info_time}\$//"`

                # Пропускаем неверно сформированные записи
                if [[ "$resume_info_time" == "" || "$resume_info_name" == "" ]]
                then
                        mplayer_ext_warning "Bad resume info string: '$resume_info'."
                        continue
                fi
                
                # Если это тот файл, который мы ищем
                if [[ "$resume_info_name" == "$1" ]]
                then
                        # Пропускаем старую запись
                        continue
                # Остальные файлы - оставляем без изменений
                else
                        resume_info_array[$((i++))]="$resume_info"
                fi
        done

        # Если видео не досмотрели до конца
        if [[ "$2" != "0" ]]
        then
                mplayer_ext_echo "Writing resume time information: '$1': $2."
                resume_info_array[$i]="$1:$2"
        else
                mplayer_ext_echo "Writing resume time information: '$1': viewed."
        fi

        # Заносим изменения в файл
        echo "${resume_info_array[*]}" > "$resume_info_file" || die
}

# Получает строку времени, на котором было приостановлено воспроизведение файла.
# Преобразует строки вида:
# A: 308.4 V: 308.4 A-V:  -0.006 ct:  -0.041 7395/7395  4%  0%  5.5% 0 0
# A: 308.4 V: 308.4 A-V:  0.006 ct:  0.041 7395/7395  4%  0%  5.5% 0 0
# A:   2.0 V:   2.0 A-V: -0.006 ct:  0.007  50/ 50  6%  3%  3.9% 0
# A:  87.6 (01:27.5) of 228.0 (03:48.0)  4.4%
# V:   1.8  45/ 45 15%  3%  0.0% 0 0
# в строку вида:
# [AV]:308
# в зависимости от наличия в файле аудио/видео дорожек
get_cur_pos_info()
{
        local pos_info=`cat $tmp_file | head --lines $end_line | tail --lines $((end_line - start_line + 1)) | tr '\33\15' '\n' \
                | egrep '^[AV]:[[:space:]]*[[:digit:]]+\.[[:digit:]]+[[:space:]]+' \
                        | tail --lines 1 \
                                | sed -r 's/:\s+/:/g' | sed -r 's/\s+/ /g'`

        if [[ $pos_info == "" ]]
        then
                return 1
        fi

        # Видео со звуком
        if echo "$pos_info" | egrep -o '^A:[[:digit:]]+\.[[:digit:]]+ V:[[:digit:]]+\.[[:digit:]]' > /dev/null
        then
                pos_info=`echo -n "$pos_info" | awk '{ print $2 }' | awk -F '.' '{ print $1 }'`
        # Видео без звука
        elif echo "$pos_info" | egrep -o '^V:[[:digit:]]+\.[[:digit:]]' > /dev/null
        then
                pos_info=`echo -n "$pos_info" | awk -F '.' '{ print $1 }'`
        # Аудио без видео
        elif echo "$pos_info" | egrep -o '^A:[[:digit:]]+\.[[:digit:]]' > /dev/null
        then
                pos_info=`echo -n "$pos_info" | awk -F '.' '{ print $1 }'`
        # Логическая ошибка
        else
                die "Logical error!"
        fi

        if [[ $pos_info == "" ]]
        then
                die "Logical error!"
        fi

        echo -n "$pos_info"
}

get_resume_pos()
{
        local resume_info resume_info_time resume_info_time

        # Устанавливаем разделитель слов равным \n
        local IFS=$'\n'

        for resume_info in $(< "$resume_info_file")
        do
                resume_info_time=`echo "$resume_info" | egrep '^.+:[[:digit:]]+$' | sed -r 's/^.+://' | egrep '^[[:digit:]]+$'`
                resume_info_name=`echo "$resume_info" | sed "s/:${resume_info_time}\$//"`

                # Пропускаем неверно сформированные записи
                if [[ "$resume_info_time" == "" || "$resume_info_name" == "" ]]
                then
                        # Предупреждение не выводим, т. к. оно будет выведено при записи в файл.
                        continue
                fi
                
                # Если это тот файл, который мы ищем
                if [[ "$resume_info_name" == "$1" ]]
                then
                        echo $resume_info_time
                        return 0
                fi
        done

        return 1
}

if ! tmp_file=`mktemp`
then
        die "Can't create temp file."
fi

if ! which mplayer > /dev/null
then
        die "Error! Mplayer not installed."
fi

if [[ ! -e "$resume_info_file" ]]
then
        touch "$resume_info_file" || die
fi

# Изменяем агрументы, переданные mplayer'у так, чтобы выбранные видеофайлы
# воспроизводились с того момента, где в прошлый раз было прервано
# воспроизведение.
i=0
for option
do
        options[$((i++))]="$option"

        if [[ ${option:0:1} != '-' ]]
        then
                # Если значение параметра похоже на имя файла, то считаем, что
                # требуется проиграть этот файл.  Если это просто значение опции, то
                # скрипт все равно сработает нормально, разве что добавится лишний
                # ключ -ss в случае когда значение параметра будет совпадать с
                # именем какого-либо файла в системе.
                if [[ -e "$option" ]]
                then
                        if video_name=`get_video_name_by_file_name "$option"`
                        then
                                # Если воспроизведение этого видео файла было прервано ранее
                                if video_resume_pos=`get_resume_pos "$video_name"`
                                then
                                        options[$((i++))]='-ss'
                                        options[$((i++))]="$video_resume_pos"
                                fi
                        fi
                fi
        fi
done

# Запускаем mplayer с измененными параметрами командной строки
mplayer_ext_echo "Starting mplayer: mplayer ${options[@]}"
mplayer "${options[@]}" | tee "$tmp_file"

# Получаем все файлы, которые проигрывал mplayer -->
        files_in_output="`egrep --line-number 'Playing[[:space:]]+.+\.' $tmp_file`"

        for line in `seq \`echo "$files_in_output" | wc --lines\``
        do
                file_in_output=`echo "$files_in_output" | head --lines $line | tail --lines 1`
                files_lines[$((line-1))]=`echo "$file_in_output" | awk -F ':' '{ print $1 }'`
                files_paths[$((line-1))]=`echo "$file_in_output" | sed -r 's/^[[:digit:]]+:Playing[[:space:]]+//' | sed 's/\.$//g'`
        done
# Получаем все файлы, которые проигрывал mplayer <--

# Получаем всю необходимую информацию о каждом проигранном файле -->
        for num in `seq 1 ${#files_lines[*]}`
        do
                i=$((num-1))

                start_line=${files_lines[$i]}

                # Генерируем имя видео по имени файла
                if ! video_name=`get_video_name_by_file_name "${files_paths[$i]}"`
                then
                        mplayer_ext_echo "Skiping file '${files_paths[$i]}'"
                        continue
                fi

                # Если файл последний
                if [[ $num -eq ${#files_lines[*]} ]]
                then
                        end_line=$((`cat $tmp_file | wc --lines` + 1))

                        # Получаем строку со временем, на котором остановилось воспроизведение
                        if ! video_resume_string=`get_cur_pos_info`
                        then
                                # Получить строку не удалось - это может произойти по разным причинам,
                                # например, если не удалось открыть файл.
                                # Т. к. файл не проигрывался, то не запоминаем его позицию.
                                mplayer_ext_echo "Skiping file '${files_paths[$i]}'"
                                continue
                        fi

                        # Файл проигрался до конца
                        if [[ `cat $tmp_file | tail --lines 1` == 'Exiting... (End of file)' ]]
                        then
                                set_resume_pos "$video_name" 0
                        # Проигрывание файла было прервано
                        else
                                video_resume_time=`echo -n "$video_resume_string" | awk -F ':' '{ print $2 }'`

                                # Видео (для аудио отматывать не надо)
                                if [[ `echo -n "$video_resume_string" | awk -F ':' '{ print $1 }'` == 'V' ]]
                                then
                                        # "Отматываем" видео назад (приблизительно) до предыдущего ключевого кадра
                                        if [[ $((video_resume_time - keyint)) -lt 0 ]]
                                        then
                                                video_resume_time=0
                                        else
                                                video_resume_time=$((video_resume_time - keyint))
                                        fi
                                fi

                                set_resume_pos "$video_name" "$video_resume_time"
                        fi
                # Файл не последний
                else
                        end_line=${files_lines[$((i+1))]}

                        # Получаем строку со временем, на котором остановилось воспроизведение
                        if ! video_resume_string=`get_cur_pos_info`
                        then
                                # Получить строку не удалось - это может произойти по разным причинам,
                                # например, если не удалось открыть файл.
                                # Т. к. файл не проигрывался, то не запоминаем его позицию.
                                mplayer_ext_echo "Skiping file '${files_names[$i]}'"
                                continue
                        fi

                        set_resume_pos "$video_name" 0
                fi
        done
# Получаем всю необходимую информацию о каждом проигранном файле <--

cleanup

Изменение размера фото с Imagemagick

Imagemagick может творить с фотографиями всё, что вам угодно!

Чаще всего я его использую, чтобы быстро сжать (resize) в размере много фотографий для заливки в Интернет. С помощью одной команды все картинки становятся одного размера:

mogrify -resize x600 *.JPG

Здесь mogrify выполняет роль команды convert, но делает это с заменой исходного файла. Параметр x600 просит Imagemagick изменить размер по вертикали с сохранением пропорций по горизонтали.