简介

本文将尝试指出在PHP Web脚本中使用FFmpeg时需要了解的所有重要事项。它还将显示一些使用示例,以使事情更清楚。这个想法也可以应用到其他web脚本语言。

从PHP脚本调用命令行工具

选择一个模型

网页设计为快速执行,以便浏览您的网站的人不必等待太多的响应。因为如果他们无聊的等待,他们只会导航到另一个,更灵敏(通常是您的竞争对手的)网站。话虽如此,你可以做的最糟糕的事情是从你的web脚本运行一个命令行工具(如ffmpeg),并等待它完成处理,以便能够将结果返回到等待在线用户(异常这是小/快的工具,其执行时间太小而不能注意到)。

您想要做的是将命令行工具的长处理与Web脚本执行分开,以使脚本更具响应性。所以,你有至少两个选项:

  1. 运行命令行工具(使用了shell_exec()在后台为例),并继续与web脚本执行,定期刷新状态页面,显示当前进度

  1. 创建一个新的“作业”(通常是数据库表中的一个新行),并有一些背景“工作”进程(cron作业,shell脚本,批处理脚本),它将监视“作业列表”需要处理的新工作

这两种方法看起来是一样的,但是他们不是。最重要的区别是,第二种方法可以更好地扩展更高的网站流量,因为它允许“工作”进程在完全独立的机器上运行。此外,可以有几个“工作”机器,一起工作,分裂工作负载,涉及小的同步。

第一种方法通常是大多数想要快速完成工作的人的首选,但是在他们的网站变得流行的时间,他们的web服务器变得不那么敏感,由于不断的cpu饥饿,由多个命令行工具(ffmpeg实例)在后台运行。在那一刻,他们通常开始考虑第二种方法。

在后台运行的ffmpeg

以下示例适用于基于Linux的操作系统。对于基于Windows的操作系统,请继续阅读本文,而是你读了之后,也看到了如何使用START和CMD后台运行的过程。这将给你一个想法如何应用相同的逻辑到基于Windows的操作系统。

让我们考虑从PHP脚本运行ffmpeg的自然方式:

<?php
echo "Starting ffmpeg...\n\n";
echo shell_exec("ffmpeg -i input.avi output.avi &");
echo "Done.\n";
?>

这里有几个问题需要指出。第一个是,虽然我们指定我们希望在后台执行ffmpeg(使用和号运算符“&”),PHP脚本将不会继续执行,直到ffmpeg完成其执行。这是由于这样的事实,在该票据中提及了PHP的exec()函数,上面写着:

如果程序使用此函数启动,为了使其在后台继续运行,程序的输出必须重定向到文件或另一个输出流。如果不这样做,将导致PHP挂起,直到程序的执行结束。

不要混淆的例子显示了shell_exec()调用,而不是EXEC()。所有的PHP的程序执行功能共享相同的代码库和限制。

所以,要解决这个问题,我们需要做这样的事情:

<?php
echo "Starting ffmpeg...\n\n";
echo shell_exec("ffmpeg -i input.avi output.avi >/dev/null 2>/dev/null &");
echo "Done.\n";
?>

该说的部分“ >的/ dev / null的 ”将FFmpeg的实例的标准输出(stdout)重定向到/ dev / null的(有效地忽略输出)和“ 2>的/ dev / null的 ”将重定向标准错误(错误)到/ dev / null(有效地忽略任何错误日志消息)。这两个可以组合成一个较短的表示:“ >的/ dev / null的2>&1 ”。如果你喜欢,你可以阅读更多关于I / O重定向

这里应该提到一个重要的注意事项。ffmpeg命令行工具使用stderr输出错误日志消息,并且保留stdout用于可能使用的管道(将从ffmpeg生成的输出媒体流重定向到其他命令行工具)。也就是说,如果你在后台运行你的ffmpeg,你很可能想把stderr重定向到一个日志文件,以便能够检查它。

需要注意的另一件事是标准INPUT(stdin)。命令行ffmpeg工具被设计为一个交互式实用程序,它接受用户的输入(通常来自键盘),并在用户的当前屏幕/终端上报告错误日志。当我们在后台运行ffmpeg时,我们想要告诉ffmpeg没有从stdin接受任何输入(也不等待)。我们可以告诉这ffmpeg的,再次使用I / O重定向“ <的/ dev / null的 ”,这样最后一个例子,安全运行ffmpeg的命令行工具在后台将与此类似:

<?php
echo "Starting ffmpeg...\n\n";
echo shell_exec("ffmpeg -y -i input.avi output.avi </dev/null >/dev/null 2>/var/log/ffmpeg.log &");
echo "Done.\n";
?>

“-y”选项用于自动覆盖输出文件(output.avi)不要求是/否确认。如果需要相反的情况,如果输出文件已经存在,要自动取消整个过程,请改用“-n”选项。

包装库

一些PHP库允许将ffmpeg调用包装到PHP对象中,并且如果您不喜欢使用命令行,可以为您提供一个不错的语法。其中之一是在积极维护PHP-FFmpeg的。它只需要你下载一个最新的ffmpegffprobe从安装PHP组件构建分开。然后你可以这样运行PHP代码:

$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open('video.mpg');
$video->filters()
->resize(new FFMpeg\Coordinate\Dimension(320, 240))
->synchronize();
$video->save(new FFMpeg\Format\Video\X264(), 'export-x264.mp4')

当然,你需要在后台运行这样的任务。图书馆如GearmanClient促成。

注: ffmpeg的- PHP的是,2007年以来未开发的扩展名(和要求“的ffmpeg-0.4.9_pre1或更高版本”),这意味着你仅限于使用一种非常古老的版本的ffmpeg,没有可能把它更新到最新版本。由于进行了大量的更改/改进,在ffmpeg的代码中,每天,它使得ffmpeg-php与最新的ffmpeg不兼容。

案例成功测试结果:

<?php
echo "正在启动ffmpeg...\n\n";
echo shell_exec("ffmpeg -y -i rtmp://tinywan.123.com/live/4001483413136 -c copy -f flv rtmp://131.180/live/4001483492781?vhost=13.168 </dev/null >/dev/null 2>/var/log/ffmpeg.log &");
echo "完成.\n";
正在启动ffmpeg...

完成.

日志文件:

ffmpeg version 2.3.git Copyright (c) 2000-2014 the FFmpeg developers
built on Sep 1 2014 19:01:47 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
configuration: --prefix=/usr/local/ffmpeg/build --extra-cflags=-I/usr/local/ffmpeg/build/include --extra-ldflags=-L/usr/local/ffmpeg/build/lib --bindir=/usr/local/ffmpeg/bin --enable-gpl --enable-libass --enable-libfaac --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-openssl --enable-libspeex --enable-libxvid
libavutil 54. 7.100 / 54. 7.100
libavcodec 56. 1.100 / 56. 1.100
libavformat 56. 3.100 / 56. 3.100
libavdevice 56. 0.100 / 56. 0.100
libavfilter 5. 0.103 / 5. 0.103
libswscale 3. 0.100 / 3. 0.100
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 0.100 / 53. 0.100
[flv @ 0x2862000] Stream discovered after head already parsed
Last message repeated 1 times
Input #0, flv, from 'rtmp://tinywan.3213.com/live/4001483413136':
Metadata:
Server : Tengine
displayWidth : 1920
displayHeight : 1080
fps : 25
profile :
level :
Duration: 00:00:00.00, start: 765.097000, bitrate: N/A
Stream #0:0: Video: h264 (High), yuv420p(tv, bt709), 1920x1080, 1048 kb/s, 25 fps, 25 tbr, 1k tbn, 2k tbc
Stream #0:1: Data: none
Stream #0:2: Audio: aac, 44100 Hz, stereo, fltp
Output #0, flv, to 'rtmp://1232130/live/4001483492781?vhost=321312':
Metadata:
Server : Tengine
displayWidth : 1920
displayHeight : 1080
fps : 25
profile :
level :
encoder : Lavf56.3.100
Stream #0:0: Video: h264 ([7][0][0][0] / 0x0007), yuv420p, 1920x1080, q=2-31, 1048 kb/s, 25 fps, 1k tbn, 1k tbc
Stream #0:1: Audio: aac ([10][0][0][0] / 0x000A), 44100 Hz, stereo
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:2 -> #0:1 (copy)
Press [q] to stop, [?] for help

测试成功!

 

参考文献:http://trac.ffmpeg.org/wiki/PHP

PHP基础知识之————PHP Web脚本中使用FFmpeg的更多相关文章

  1. 《JAVASCRIPT高级程序设计》表单基础知识和文本框脚本

    在HTML中,表单是由<form>元素来表示,在javascript中,表单对应的是HTMLFormElement类型,它具有一些独有的属性和方法: 一.表单基础知识 1.取得表单的方式 ...

  2. C#基础知识汇总(不断更新中)

    ------------------------------目录---------------------------- 1.隐式类型2.匿名类型3.自动属性4.初始化器5.委托6.泛型7.泛型委托8 ...

  3. 视频基础知识:浅谈视频会议中H.264编码标准的技术发展

    浅谈视频会议中H.264编码标准的技术发展 浅谈视频会议中H.264编码标准的技术发展 数字视频技术广泛应用于通信.计算机.广播电视等领域,带来了会议电视.可视电话及数字电视.媒体存储等一系列应用,促 ...

  4. java基础知识汇总(持续更新中....)

    1.java四大特性:抽象.继承.封装,多态 构造函数: http://blog.csdn.net/qq_33642117/article/details/51909346 2.java数据基本类型: ...

  5. Java基础知识强化106:Java中 int 的各进制之间的转换

    1.二.八.十.十六进制之间的转换  下面是示例代码,我们直接通过JDK工具库中的方法实现的,如下: public static Integer valueOf(String s, int radix ...

  6. Java基础知识强化101:Java 中的 String对象真的不可变吗 ?

    1. 什么是不可变对象?       众所周知, 在Java中, String类是不可变的.那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对 ...

  7. Java基础知识强化03:Java中的堆与栈

    1.在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题. 一般,JV ...

  8. Java基础知识强化13:Java中单例模式案例使用(懒汉式)

    1.古往今来历史上皇帝通常只有一人.为了保证其唯一性,古人采用增加"防伪标识"的办法,如玉玺.更为简单的办法就是限制皇帝的创建.本案例中就是使用单例模式从而保证皇帝的唯一性.实例运 ...

  9. Java基础知识强化12:Java中运用数组的四种排序方法

    1.使用JavaApi文档中的Arrays类中的sort()进行快速排序 首先我们直接看代码如下: package himi.text; import java.util.Arrays; public ...

随机推荐

  1. kali 下文件操作

    记得看到一片文章中说要学习linux 不要用kali.. 不感兴趣的东西,还指望我去搞个Ubuntu.... Ctrl+I 清屏 CD命令: cd 进入用户主目录: cd ~ 进入用户主目录: cd ...

  2. scp 从远程拷贝文件不需要密码

    执行这一句,弹出来要你输入密码,输入一次后,以后再 scp 远程机的文件  再也不需要密码了 ssh-copy-id myusername@8.8.8.8

  3. Uploadify/uploadifive上传(中文文档)

    Uploadify是一款基于JQuery的优秀的文件/图片上传的插件,有基于Flash和HTML5两种版本.  Uploadify/uploadifive主要特点有: 1. 多文件上传 2. 个性化设 ...

  4. ZOJ-1239 Hanoi Tower Troubles Again!

    链接:ZOJ1239 Hanoi Tower Troubles Again! Description People stopped moving discs from peg to peg after ...

  5. 约在CBD,吃饭

    午饭当然是外卖. CBD上班的同仁们不用约,都去了一间叫“大食堂”的餐厅. 它在商业街繁华地段的二楼,有1000平米.你不知道么,餐馆们都躲到找不着的角落,变成了厨房,这里的租金便宜得很.但它不做饭, ...

  6. iOS 简单的分段下载文件

    首先自己写个请求数据的类 首先.h文件 #import <Foundation/Foundation.h> @interface Downloaders : NSObject<NSU ...

  7. 运用node的文件系统模块批量修改文件名

      如果我们需要大批量修改一个文件中的名称,比如,删除文件名中的副本时,就可以借助node的文件系统模块,快捷快速的完成. 首先建立一个js文件(changeName.js),代码如下: // 引入f ...

  8. WebBrowser内核指定

    一.背景 这几天在维护公司的一个项目,嗯…到现在七八年没人动过了(也是老古董了),都说N年前的代码碰不得 处处是坑 不能挖坑还得一步一步的填坑,恰好今天就填了一坑 此处作为记录 供以后翻阅,对代码除了 ...

  9. jquery.min.map 404 (Not Found)出错的原因及解决办法

    Chrome 更新后出现了 jquery.min.map 404  (Not Found) 的信息 这个到底是什么东西?查询了一下,得到了以下资料 JQuery 官方解释 摘录一下內容 从 jQuer ...

  10. backbone实例01

    backbonejs往简单说,就是一前端MVC框架,适合用于单页面.复杂的前端逻辑. 直接上代码,里面都有相关注释,重点是理解清楚view.collection.model这三者如何关联调用. < ...