Php работа с видеофайлами

Работа с видео на php с помощью php ffmpeg

1. качаем уже собранный php ffmpeg от Sergey Fedotov
2. распаковываем архив
3. копируем файл php_ffmpeg.dll в папку php/extensions
4. копируем файлы avformat-51.dll, avcodec-51.dll, avutil-49.dll ,pthreadGC2.dll в папку windows/system32
5. добавляем в php.ini строку: extension=php_ffmpeg.dll
6. перезапускаем Apache
7. проверяем всё ли у нас получилось var_dump(extension_loaded(‘ffmpeg’)) или через phpinfo()

скорей всего у нас получилось так что ознакомимся с функциями =)

Перевод официальной документации (API Docs)

$movie = new ffmpeg_movie(String path_to_media, boolean persistent)
Открыть аудио или видео файл и Вернёт объект.
path_to_media — Путь к аудио или видео файлу
persistent — Открыть как постоянный ресурс. О постоянных ресурсах
читайте в документации по PHP

$movie->getDuration()
Вернёт продолжительность аудио или видео файла в секундах.

$movie->getFrameCount()
Вернёт количество кадров (фреймов) аудио или видео файла.

$movie->getFrameRate()
Вернёт частоту кадров видео в кадрах в секунду (fps — frame persecond)

$movie->getFilename()
Вернёт путь к видео или аудио файлу

$movie->getComment()
Вернёт поле комментария из аудио или видео файла

$movie->getTitle()
Вернёт поле заголовка из аудио или видео файла

$movie->getAuthor() псевдоним $movie->getArtist()
Вернёт поле «автор» из видео файла или «автор» из ID3 поля mp3 файла

$movie->getCopyright()
Вернёт поле «авторское право» из аудио или видео файла

$movie->getArtist()
Вернёт ID3 поле «Артист» из mp3 файла

$movie->getGenre()
Вернёт ID3 поле «Жанр» из mp3 файла

$movie->getTrackNumber()
Вернёт ID3 поле «номер дорожки» из mp3 файла

$movie->getYear()
Вернёт ID3 поле «Год» из mp3 файла

$movie->getFrameHeight()
Вернёт высоту видео в пикселях

$movie->getFrameWidth()
Вернёт ширину видео в пикселях

$movie->getPixelFormat()
Вернёт формат пикселов видео

$movie->getBitRate()
Вернёт скорость потока(битрейт) видео или аудио файла в битах в
секунду

$movie->getVideoBitRate()
Вернёт скорость потока(битрейт) видео в битах в секунду.
Замечание : Работает только с файлами у которых постоянный битрейт

$movie->getAudioBitRate()
Вернёт скорость потока(битрейт) аудио у видео или аудио файла в
битах в секунду.

$movie->getAudioSampleRate()
Вернёт скорость дискретизации аудио у видео или аудио файла в битах
в секунду.

$movie->getFrameNumber()
Вернёт текущий номер кадра.

$movie->getVideoCodec()
Вернёт название видео кодека который использован для видео файла
как строку

$movie->getAudioCodec()
Вернёт название аудио кодека который использован видео файл как
строку

$movie->getAudioChannels()
Вернёт количество аудио каналов (1 моно 2 стерео и т д) как целое
число

$movie->hasAudio()
Вернёт логическое значение соответствующие наличию или отсутствию
аудио

$movie->getFrame([Integer framenumber])
Вернёт кадр из видео как ffmpeg_frame объект. Возратит логическую
ложь (false) если кадра нет
framenumber -Номер кадра который надо возратить. Если framenumber
не определен то возращается следующий кадр из видео.

$movie->getNextKeyFrame()
Вернёт следующий ключевой кадр как ffmpeg_frame объект. Возратит
логическую ложь (false) если кадра нет

ffmpeg_frame object methods

$frame = new ffmpeg_frame(Resource gd_image)
Создаст обьект ffmpeg_frame из ресурса GD картинки.
Замечание : Функция недоступна если нет библитеки GD.

$frame->getWidth()
Вернёт ширину кадра.

$frame->getHeight()
Вернёт высоту кадра.

$frame->getPTS() alias $frame->getPresentationTimestamp()
Возвращает время создания кадра.

$frame->resize(Integer width, Integer height [, Integer crop_top [,
Integer crop_bottom [, Integer crop_left [, Integer crop_right ]]]])

Изменяет размер и обрезает кадр (Обрезание встроено в изменение
размера картинка ffmpeg и сделал его для полноты)
width — Новая ширина кадра (должено быть натуральным числом)
height — Новая высота кадра (должено быть натуральным числом)
croptop — Удалить [croptop] рядов пикселов с верху кадра.
cropbottom — Удалить [cropbottom] рядов пикселов с низу кадра.
cropleft — Удалить [cropleft] рядов пикселов с лева у кадра..
cropright Удалить [cropright] рядов пикселов с права у кадра..

Замечание: Обрезание всегда происходит до измения размера кадра.
Значения параметров обрезания должны быть натуральными числами.

$frame->crop(Integer crop_top [, Integer crop_bottom [, Integer
crop_left [, Integer crop_right ]]])

Обрезать кадр.
croptop — Удалить [croptop] рядов пикселов с верху кадра.
cropbottom — Удалить [cropbottom] рядов пикселов с низу кадра.
cropleft — Удалить [cropleft] рядов пикселов с лева у кадра..
cropright Удалить [cropright] рядов пикселов с права у кадра..

Замечание : Параметры должны быть натуральными числами

$frame->toGDImage()
Возвращает truecolor GD картинку (ресурс) кадра
Замечание : Функция недоступна если нет библитеки GD.

ffmpeg_animated_gif

$gif = new ffmpeg_animated_gif(String output_file_path, Integer width,
Integer height, Integer frame_rate, [Integer loop_count])

Создает новый ffmpeg_animated_gif обьект

output_file_path — Путь в файловой системе куда будет записан
анимированный gif .
width — Ширина анимированого gif’а
height — Высота анимированного gif’а
frame_rate — Частота кадров анимированного gif’а в кадрах в
секунду
loop_count — Количество повторений анимации. Укажите 0 для
бесконечного повторения или пропустите параметр для отключения
повторений.

$frame->addFrame(ffmpeg_frame frame_to_add)
Добавляет кадр в конец анимированного gif’а.
frame_to_addffmpeg_frame обьект для добавления в конец
анимированного gif’а.

Теперь рассмотрим некоторые примеры

1. Узнаём информацию о видео файле .

// получаем продолжительность и размеры видео

$movie = new ffmpeg_movie("/www/1.avi");
echo "Продолжительность фильма: ";
// так как мы получаем секунды надо нам их перевести в человечный вид ЧЧ:ММ:CC
// для этого мы и используем функцию gmdate я думаю фильмов длиной по несколько дней у вас нет =)
echo "".gmdate("H:i:s",$movie->getDuration())."
";

// теперь выведем размерв нашего фильма
echo "Размеры фильма: ";
echo "".$movie->getFrameWidth()." x ".$movie->getFrameHeight()."";

?>
//получаем скриншот по средствам php ffmpeg

// путь до файла
$file = "/www/1.avi";
// кадр который будем выхватывать
$frame = 150;

// получаем кадр
$movie = new ffmpeg_movie($file);
$image = $movie->getFrame($frame);
$show_img = $image->toGDImage();

// выводим его
header("Content-type: image/jpeg");
imagejpeg($show_img);
imagedestroy($show_img);
?>

3. Получаем и редактируем кадр.

// получаем скриншот по средствам php ffmpeg и уменьшаем его

// путь до файла
$file = "/www/1.avi";
// кадр который будем выхватывать
$frame = 150;
// максимальный размер по высоте
$max_width = 150;

// получаем кадр в gd
$movie = new ffmpeg_movie($file);
$image = $movie->getFrame($frame);
$show_img = $image->toGDImage();

// редактируем то что в gd
$new_image = new ffmpeg_frame($show_img);
//вычисляем старые значения ширины и высоты
$old_width = $new_image->getWidth();
$old_heighgt = $new_image->getHeight();
// соотношение сторон
$mov_ratio = $old_width/$old_heighgt;
if($old_width > $max_width) $new_width = $max_width;
>
// задаём новые параметры
$new_height = $new_width / $mov_ratio;
// изменяем размер
$new_image->resize($new_width, $new_height);
$new_show_img = $new_image->toGDImage();

// выводим его
header("Content-type: image/jpeg");
imagejpeg($new_show_img);
imagedestroy($new_show_img);

?>

4. Создаём анимированный GIF.

// создаём анимированый гиф
// путь до файла
$file = "/www/1.avi";

// поехали =)
$movie = new ffmpeg_movie($file);

// создаём анимацию
$gif=new ffmpeg_animated_gif("/www/primer.gif",100 ,100 ,24);

for ($frame = 150; $frame $image = $movie->getFrame($frame);
$gif->addFrame($image);
>

?>

Источник

Потоковая загрузка и обработка видео посредством node.js + php и ffmpeg — часть первая

Работаю в аутсорсинговой компании и как-то встала задача загрузки видео с возможностью последующей обработки для внутренних нужд приложения: ресайз до нужного размера, конвертирование к нужному формату, вытягивание аудио-дорожек (если таковые присутствуют), раскадровка видео. В конце результаты нужно сохранить в облачном хранилище для последующего использования в онлайн-редакторе. Требования: масштабируемость, неограниченый размер видео, скорость, кроссбраузерность, наглядность.

Поскольку тема очень обширная, разделю ее на разделы:

  1. Общие проблемы, нюансы, с которыми пришлось столкнуться
  2. Загрузка видео (на этой теме, пожалуй, не буду останавливаться, поскольку она уже поднималась в этом и этом посте.
  3. Обработка видео.
  4. Сохранение в облачном хранилище.

Часть первая

1. Кроссбраузерность
Для того, чтобы обеспечить это требование нельзя было использовать HTML5 загрузку файлов (не во всех браузерах она реализована). Поэтому мы пошли путем создания обычной HTML4 формы, которая сабмитилась на сервер с node.js. Для того, чтобы получить текущий прогресс загрузки/обработки видео создавались AJAX-запросы. В форму включался случайно сгенерированная строка-идентификатор (например, 32 символа). Node.js привязывал к ней информацию по текущему файлу и при каждом запросе состояния передавал вот такой JSON:

На основании этого пользователь видит состояние загрузки.

2. Авторизация пользователя
Поскольку фронтенд на PHP (там же происходит авторизация пользователя) нужно было как-то передать данные сессии на сервер node.js. Для этих целей использовался memcached. О подмене сессий в PHP можно прочесть тут. Суть проста: сессии сохраняются в memcached, при загрузке через форму передается session_id, который считывается node.js. Далее node.js обращается к memcached в поисках соответствущей сессии, берет user_id и т.д. Здесь есть один важный момент: session_id в самой форме нужно ставить вначало, потому что POST-запрос передает параметры в порядке их следования в HTML. То есть, если мы сделаем так:

В таком случае к node.js сначала прийдет сам файл, а потом session_id, что не есть хорошо. Ведь нам нужно сначала знать, от кого приходит файл и отменить в случае, если пользователь не авторизирован. Если в примере выше поменять местами file и session_id, то сначала мы получаем сессию, притормаживаем загрузку файла, и ждем пока сервер проверит, все ли в порядке с пользователем и только тогда продолжаем загрузку. В node.js можно ставить request на паузу.

3. Потоковая обработка видео
Проблема в том, что не все видео может быть обработано сразу. Например, по спецификации mp4 формата метаданные идут в конце файла. А нам ведь нужно сразу знать какие размеры у видео, какие дорожки есть в файле, длительность и т.д. Плюс к этому некоторые форматы видео при перекодировке нуждаются, чтобы была возможность обращаться к разным частям исходного файла. Исходя из этого есть два случая с двумя вариантами вариантами каждый:

1. Вначале загрузки, когда мы вытягиваем командой ffmpeg информацию о файле, используя node.js:

var spawn = require('child_process').spawn; var ffmpeg = spawn('ffmpeg', ['-i', '-']); var ffmpeg_stdout = '' ffmpeg.stderr.on('data', function(buffer) < ffmpeg_stdout += buffer; // Получаем информацию о файле >); // file - берется с нашей формы file.on('data', function(buffer) < ffmpeg.stdin.write(buffer); >); 

В переменной ffmpeg_stdout мы получим все дорожки, которые содержатся в файле или ошибку. Если есть ошибка, значит ffmpeg не может обработать файл потоком. В таком случае предупреждаем пользователя об этом и загружаем весь файл сразу, и только после этого производим нужные операции.

2. В данном случае скорость важна, поэтому мы пытаемся запустить раскадровку, как только видео только началось загружаться. Но если формат не поддерживает потоковую обработку, то приходится ждать момента полной загрузки.
Получается такой алгоритм: возможно извлечь метаданные, тогда пытаемся налету обработать видео, если и это получается, то радуемся, во всех остальных случаях ждем полной загрузки. На практике лишь небольшое количество видео требуется загружать полностью, чтобы начать обработку.

На сегодня пожалуй все, завтра утром на работу.

Хотел бы завершить на мажорной ноте: возможности безграничны, можно распределить нагрузку на несколько серверов, на ходу показывать результаты, например вытягивать последний готовый фрейм из видео. Работает это все на Amazon EC2. По скорости могу сказать, что скорость загрузки не было возможности проверить (канал слабый), но не меньше 10мбит, думаю точно. А по нагрузке на сервер: Middle server в одиночку одно видео тянет где-то 2Мбит видео, то есть загрузка ушла далеко вперед, а обработка не поспевает. Наибольшее время занимает ресайз. Раскадровка и вытягивание аудио-дорожки относительно быстро происходит.

Если пост понравится, опишу реализацию и механизм работы более подробно в следующие разы.

Скриншоты того, что получилось. Сразу оговорюсь, это еще не рабочий вариант, поэтому строго не судите:

Источник

Читайте также:  Lotospc by refuelling index php
Оцените статью