четверг, 13 августа 2015 г.

Просто о git

Постараюсь как можно проще описать работу с системой управления версиями – Git.
Для начала хотелось бы сказать о плюсах – распределённые системы управления версиями позволяют работать не имея никакого сервера с хранилищем репозитория, это означает, что можно использовать git просто для отслеживания изменений в одном единственном файле, чтобы была возможность откатить изменения, при этом не плодить кучу копий, в которых легко запутаться.
Здесь я хочу описать git лишь с точки зрения отслеживания версий локальных файлов, без использования репозиториев на общем сервере и совместной работы с ним несколькими пользователями.

Установка

 Для установки пользователям линукс достаточно в консоли ввести команду для установки git, например, для Debian это:
# apt-get install git
Также можно установить удобные графические утилиты: git-gui, git-gtk, gitg и т.д. Gitg, например, позволяет вообще не вникать в суть команд, если не требуется каких-то более сложных действий, чем создание коммитов и переход между ветками.
Для пользователей Windows можно скачать git с сайте git-scm.com, однако, при добавлении в репозиторий файлов с русскими названиями, может возникнуть проблема, в этом случае лучше установить cygwin и при установке выбрать один из пакетов – git (он во вкладке devel, если я не ошибаюсь).

Создание репозитория

Для создания репозитория есть два пути: создать новый или клонировать существующий. Для создания репозитория вводим в папке с файлами, версии которых нужно отслеживать:
$ git init
Очень просто. Чтобы клонировать существующий репозиторий нужно ввести:
$ git clone protocol://url
где protocol – протокол, по которому будет производиться передача данных. Git умеет работать с множеством протоколов: http, https, ftp, ssh, git (собственный протокол), file (если репозиторий хранится локально). url – это адрес, который вы должны знать, раз собрались клонировать чей-то репозиторий.

Добавление данных и их фиксация

Для добавления данных в репозиторий служит две команды: add и commit. Первая добавляет файлы в "кэш" репозитория, вторая фиксирует данные.
$ git add <список файлов или .>
$ git commit
Если ввести commit с индексом -a, то автоматически будут добавлены файлы, которые изменились и ранее были добавлены в репозиторий. С ключём '-m <сообщение>' можно добавить сообщение, которое будет показываться при просмотре истории. Если ключ -m не указан, то будет открыт текстовый редактор, в котором это сообщение можно будет ввести, т.е. сообщение – обязательно.
Собственно, фиксация – это и есть "версия" или "коммит", т.е. если файлы будут регулярно изменяться, а мы будет эти изменения фиксировать, то в дальнейшем можно перемещаться от версии к версии, при этом все файлы, ранее добавленные, будут в том состоянии, в котором они были на момент фиксации.

Переход к определённой версии

Допустим, мы сделали какие-то изменения в каталоге, зафиксировали, и хотим вернуться к какой-то более старой версии. Для этого существует команда checkout:
$ git checkout <версия>
Версия указывается либо в виде тега (об этом ниже) или названия ветви (тоже ниже), либо в виде идентификатора коммита, который можно посмотреть, введя
$ git log
Эта команда выведет список всех версий, в начале описания каждой версии будет идти тот самый идентификатор, далее описание и т.д.
Чтобы вернуться к последней версии, нужно ввести:
$ git checkout HEAD
Если захотелось совсем отбросить последние версии, например, из-за большого количества ошибок, то нужно ввести:
$ git reset --hard <версия>
Здесь параметр --hard удалит напрочь все изменения после версии <версия>, поэтому нужно быть внимательным, вводя эту команду. Без этого параметра версии будут удалены, но все файлы в папке останутся в том состоянии, в котором они были до ввода команды, в отличие от команды checkout.

Теги

Также можно помечать определённые версии тегами, для этого существует команда tag:
$ git tag <название>
Название не должно содержать пробелов, однако можно ввести подробное описание также используя ключ -m. Посмотреть список тегов:
$ git tag
Посмотреть список тегов с описанием:
$ git tag -n
(после -n может идти число - количество строк).

Ветки

Ветки – это "ветвления" в истории версий, т.е. после определённой версии изменения могут идти по двум путям, например, один – основной, в котором предполагаются стабильные версии без критических ошибок, второй – экспериментальный, в который можно вносить любые изменения и не бояться потерять данные из первого пути.
Допустим, файлы находятся в каком-то состоянии, и мы хотим, чтобы от этого состояния можно было производить изменения по двум путям. Для этого нужно создать ветку:
$ git branch <название>
Название ветки не должно содержать пробелов. Теперь можно переключиться на эту ветку с помощью команды checkout.
Если нужно создать ветку не от текущего состояния, то используем
$ git branch <название> <версия>
Если нужно создать ветку и сразу же на неё переключиться, то:
$ git checkout -b <название> <версия>
Если не вводить версию, то ветка будет создана от текущего состояния.
При создании репозитория по умолчанию создаётся одна ветка – master.

Удаление ненужных версий

Редко, но требуется привести репозиторий в порядок и удалить из него лишние версии, например, чтобы уменьшить место, занимаемое репозиторием. (если ваш репозиторий используется несколькими людьми, то лучше так не делать, либо это должно быть оговорено с остальными пользователями, т.к. при этом действии всем придётся скачивать все версии после удалённой)
Для этого (и для многого другого) используется команда rebase, самое её простое применение:
$ rebase -i <версия>
где версия – это та версия, следом за которой будут производиться изменения в истории версий. То есть изменения можно производить в версиях, позже, чем введённая.
После ввода команды откроется текстовый редактор, в котором будет достаточно пояснений, чтобы понять, что делать. Нужно слева от версий установить определённые флаги, например, чтобы удалить версию, нужно ввести squash (все изменения просто объединятся с той версией, что выше по списку, т.е. удалится не та версия, рядом с которой ввели слово, а та, что выше), после сохранения документа будет произведено изменение истории, при этом с каждым удалённым коммитом будет предложено ввести новое описание для того коммита, с которым он был объединён. Этого можно избежать, если вместо squash ввести fixup. Кстати, можно не полностью вводить слова, а только первые буквы. Если ввести edit, то после сохранения будет запущен текстовый редактор, в котором можно изменить описание версии.

Считаю достаточным такое описание, если что вспомню, добавлю сюда. Если будет время, то опишу более подробнее, но в другом сообщении.

четверг, 6 августа 2015 г.

Захват и обработка видео из консоли

Для обработки видео существует такая утилита, как ffmpeg, которая поддерживает огромное количество кодеков и форматов аудио и видео.

Захват видео с экрана

$ ffmpeg -y -f x11grab -threads 0 -r 10 -s 1920x1080 \
-i :0.0 -preset slower -tune stillimage -an file.mkv
Описание:
  • -y – перезаписывать существующие файлы;
  • -f x11grab – запись с экрана;
  • -threads 0 – автоматически задавать максимальное количество потоков, если указать, число, то можно задать максимальное количество потоков;
  • -r 10 – кадров в секунду;
  • -s 1920x1080 – размер изображения;
  • -i :0.0 – экран для захвата (можно и удалённо), если указать :0.0+10,20 , то запись будет идти с соответствующим смещением на экране;
  • -preset slower — предустановка режима записи, существует множество (от ultrafast – самый быстрый режим с большим битрейтом, до placebo – очень медленный режим с минимальным битрейтом), лучше смотреть man x264 и подобрать настройку под производительность системы и выбранную частоту кадров;
  • -tune stillimage – предустановка для типа изображения, в данном случае - статическое изображение, т.е. запись с экрана обычных действий (игры записать не получится, для этого нужно указать film или вообще не указывать ничего);
  • -an – записывать без звука.
Кодек для записи видео можно указать явно через -vcodec …, по умолчанию для mkv используется libx264.
Для записи звука нужно указать -f oss -i /dev/dsp -acodec libfaac -ab 192k для oss (для ALSA не знаю…).
  • -f oss – запись через oss;
  • -i /dev/dsp – устройство записи (если несколько звуковых карт, указать своё);
  • -acodec libfaac – кодек записи, этот более-менее оптимальный, хотя faac гораздо хуже оригинального от nero;
  • -ab 192k — битрейт аудио.

Разрезать видео

ffmpeg -i video.mkv -ss 10:20 -t 15:00 -vcodec copy -acodec copy video2.mkv
Здесь следует сказать только о двух параметрах:
  • -ss – смещение относительно начала файла мин:сек;
  • -t – длина видео. 
Время может быть указано в формате  hh:mm:ss[.xxx] вплоть до миллисекунд.

Склеить несколько видео

Судя по всему, можно склеивать только видео формата ts и mpg. Для склеивания видео в формате mkv или mp4 с кодеком h264 видимо можно только перекодировав.
ffmpeg -i concat:"video1.mpg|video2.mpg" -vcodec copy -acodec copy video_out.mpg
Три варианта использования с перекодированием:
  • Первый вариант с последовательным перекодированием каждого видео:
    ffmpeg -i input1.avi -qscale:v 1 intermediate1.mpg
    ffmpeg -i input2.avi -qscale:v 1 intermediate2.mpg
    cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg
    ffmpeg -i intermediate_all.mpg -qscale:v 2 output.avi
    
  • Вариант с отдельным перекодированием и одновременной склейкой и обратным перекодированием средствами ffmpeg:
    ffmpeg -i input1.avi -qscale:v 1 intermediate1.mpg
    ffmpeg -i input2.avi -qscale:v 1 intermediate2.mpg
    ffmpeg -i concat:"intermediate1.mpg|intermediate2.mpg" -c copy intermediate_all.mpg
    ffmpeg -i intermediate_all.mpg -qscale:v 2 output.avi
    
  • Вариант, позволяющий делать всё параллельно (идеально подходит для многоядерных процессоров):
    mkfifo intermediate1.mpg
    mkfifo intermediate2.mpg
    ffmpeg -i input1.avi -qscale:v 1 -y intermediate1.mpg < /dev/null &
    ffmpeg -i input2.avi -qscale:v 1 -y intermediate2.mpg < /dev/null &
    cat intermediate1.mpg intermediate2.mpg |\
    ffmpeg -f mpeg -i - -c:v mpeg4 -acodec libmp3lame output.avi