ffmpeg處理視訊獲取第一幀截圖
阿新 • • 發佈:2018-12-01
<?php
//使用PHP SDK,並且使用自定義配置檔案
require app_path().'/include/BaiduBce.phar';
require app_path().'/include/SampleConf.php';
require app_path().'/include/Timer.php';
use BaiduBce\BceClientConfigOptions;
use BaiduBce\Util\Time;
use BaiduBce\Util\MimeTypes;
use BaiduBce\Http\HttpHeaders;
use BaiduBce\Services \Bos\BosClient;
use BaiduBce\Services\Bos\CannedAcl;
use BaiduBce\Services\Media\MediaClient;
class UploadController extends BaseController{
public function __construct(){
}
public function postVideoUpload()
{
set_time_limit(0);
$oTime = new Timer();
$oTime->start();
$BOS_TEST_CONFIG =
array(
'credentials' => array(
'ak' => '',
'sk' => '',
),
'endpoint' => 'http://bj.bcebos.com',
);
//呼叫配置檔案中的引數
// global $BOS_TEST_CONFIG;
//新建BosClient
$client = new BosClient($BOS_TEST_CONFIG);
$bucketName = 'btp2017/'.date('Ymd', time());
//Bucket是否存在,若不存在建立Bucket
$exist = $client->doesBucketExist($bucketName);
if(!$exist){
$client->createBucket($bucketName);
}
$fileName = $_FILES['upload_file']["tmp_name"];
$attach_filename = $_FILES['upload_file']['name'];
$attach_fileext = get_filetype($attach_filename);
$objectKey = date('YmdHis', time()).rand(1000,9999).'.'.$attach_fileext;
$response = $client->initiateMultipartUpload($bucketName, $objectKey);
$uploadId =$response->uploadId;
//設定分塊的開始偏移位置
$offset = 0;
$partNumber = 1;
//設定每塊為5MB
$fileSize = $_FILES['upload_file']['size'];
$partSize = 5 * 1024 * 1024;
$length = $partSize;
$partList = array();
$bytesLeft = $fileSize;
$e_tags = array();
//分塊上傳
while ($bytesLeft > 0) {
$length = ($length > $bytesLeft) ? $bytesLeft : $length;
$response = $client->uploadPartFromFile($bucketName, $objectKey, $uploadId, $partNumber, $fileName, $offset, $length);
array_push($partList, array("partNumber"=>$partNumber, "eTag"=>$response->metadata["etag"]));
$offset += $length;
$partNumber++;
$bytesLeft -= $length;
}
$response = $client->completeMultipartUpload($bucketName, $objectKey, $uploadId, $partList);
$switch=0;
if($switch==1){
$MEDIA_TEST_CONFIG =
array(
'credentials' => array(
'ak' => '',
'sk' => '',
),
'endpoint' => 'http://media.bj.baidubce.com',
);
//新建MediaClient
$mediaclient = new MediaClient($MEDIA_TEST_CONFIG);
$pipelineName = "btp_new_queue";
$sourceKey = $response->key;
$strs = strstr($response->key, '.');
/***********擷取縮圖***********/
$source = array("key" => $response->key);
//設定可選引數,包括縮圖輸出方法及擷取規則
$options = array(
"target" => array(
"keyPrefix" => str_replace($strs, '', $sourceKey),
"widthInPixel" => "600",
"heightInPixel"=> "450"
),
"capture" => array(
"mode" => "auto",
),
);
$thumbresponse = $mediaclient->createThumbnailJob($pipelineName, $source, $options);
/***********擷取縮圖***********/
$str = substr($strs,1);
if($str == 'mp4'){
$sFileUrl = $response->location;
// $sThumbUrl = str_replace('2017', 'mct', $response->location);
$sThumbUrl = str_replace('mp4', 'jpg', $response->location);
}else{
/**********轉碼**********/
$targetKey = str_replace($str, 'mp4', $sourceKey);
// $targetKey = "test00.mp4";
$presetName = "bce.video_mp4_1280x720_1728kbps";
$mediaresponse = $mediaclient->createSimpleJob($pipelineName, $sourceKey, $targetKey, $presetName);
$sJobId = $mediaresponse->jobId;
if($sJobId){
// $sFileUrl = str_replace('2017', 'mct', $response->location);
$sFileUrl = str_replace($sourceKey, $targetKey, $response->location);
$sThumbUrl = str_replace('mp4', 'jpg', $sFileUrl);
}
/***********轉碼***********/
}
//獲取視訊檔案時長
$responseSecond = $mediaclient->getMediaInfoOfFile("btp2017", $sourceKey);
$iSecond = $responseSecond->durationInSecond;
$oTime->stop();
if($sFileUrl && $sThumbUrl){
$time = '視訊上傳成功,用時'.$oTime->spent().'秒';
$json = array('video_url'=>$sFileUrl,'thumb_url'=>$sThumbUrl,'info'=>$time,'second'=>$iSecond);
echo json_encode($json);
die;
}else{
$time = '上傳失敗';
$json = array('video_url'=>'','info'=>$time);
echo json_encode($json);
die;
}
}else{
//ffmepeg
//路徑
//下載視訊到伺服器
$aInfo = explode('/',$response->location);
//資料夾
$jia = isset($aInfo['4']) ? $aInfo['4'] : date('Ymd');
$filename =isset($aInfo['5']) ? $aInfo['5'] : $aInfo['4'];
$sPath = "/upload/bosapi/".$jia.'/';
//$sRealPath = public_path().$sPath.'/video/';
$sRealPath = public_path().$sPath;
if( !file_exists($sRealPath)){
mkdirs($sRealPath);
}
$bucketName = 'btp2017';
try
{
$res = $client->getObjectAsString($bucketName, $jia.'/'.$filename);
file_put_contents($sRealPath.$filename,$res);
}
catch(Exception $e) {
}
// return $sRealPath.$filename;
//視訊格式
$sourceKey = $response->key;
$strs = strstr($response->key, '.');
$str = substr($strs,1);
require_once APP_ROOT.'/include/ffmpegVideo.class.php';
$ffmpegVideoInfo = new ffmpegVideoInfo();
if($str != 'mp4'){
//轉碼
$sFileNameNew = substr($filename,0,(strpos($filename,'.'))).'.mp4';
$sFileUrl = $ffmpegVideoInfo->converToMp4($sRealPath.$filename,$sPath,$sFileNameNew);
}else{
$sFileUrl = $sPath.$filename;
}
//獲取縮圖
$sThumbName = substr($filename,0,(strpos($filename,'.'))).'.jpg';
$sThumbUrl = $ffmpegVideoInfo->videoThumb($sRealPath.$filename,$sPath,$sThumbName);
//獲取視訊時長
try
{
$aVideoInfo = $ffmpegVideoInfo->video_info($sRealPath.$filename);
$iSecond = isset($aVideoInfo['seconds']) ? $aVideoInfo['seconds'] : 0;
}
catch(Exception $e) {
$iSecond = 0;
}
$json = array('video_url'=>$sFileUrl,'thumb_url'=>$sThumbUrl,'info'=>'','second'=>$iSecond);
echo json_encode($json);die;
}
}
}
ffmpeg類
<?php
class ffmpegVideoInfo{
protected $_kc_ffmpeg_path = ' /usr/local/bin/ffmpeg -i "%s" 2>&1';//ffmpeg路徑
public static $videoArr = array('flv', 'mp4');
/**
* 獲取視訊video資訊
* @param unknown_type $file
*/
public function video_info($file) {
ob_start();
passthru(sprintf($this->_kc_ffmpeg_path, $file));
$info = ob_get_contents();
ob_end_clean();
// 通過使用輸出緩衝,獲取到ffmpeg所有輸出的內容。
$ret = array();
// Duration: 01:24:12.73, start: 0.000000, bitrate: 456 kb/s
if (preg_match("/Duration: (.*?), start: (.*?), bitrate: (\d*) kb\/s/", $info, $match)) {
$ret['duration'] = $match[1]; // 提取出播放時間
$da = explode(':', $match[1]);
$ret['seconds'] = $da[0] * 3600 + $da[1] * 60 + $da[2]; // 轉換為秒
$ret['start'] = $match[2]; // 開始時間
$ret['bitrate'] = $match[3]; // bitrate 位元速率 單位 kb
}
// Stream #0.1: Video: rv40, yuv420p, 512x384, 355 kb/s, 12.05 fps, 12 tbr, 1k tbn, 12 tbc
if (preg_match("/Video: (.*?), (.*?), (.*?)[,\s]/", $info, $match)) {
$ret['vcodec'] = $match[1]; // 編碼格式
$ret['vformat'] = $match[2]; // 視訊格式
$ret['resolution'] = $match[3]; // 解析度
$a = explode('x', $match[3]);
$ret['width'] = isset($a[0]);
$ret['height'] = isset($a[1]);
}
// Stream #0.0: Audio: cook, 44100 Hz, stereo, s16, 96 kb/s
if (preg_match("/Audio: (\w*), (\d*) Hz/", $info, $match)) {
$ret['acodec'] = $match[1]; // 音訊編碼
$ret['asamplerate'] = $match[2]; // 音訊取樣頻率
}
if (isset($ret['seconds']) && isset($ret['start'])) {
$ret['play_time'] = $ret['seconds'] + $ret['start']; // 實際播放時間
}
return $ret;
}
/**
* 獲取視訊截圖
* @param unknown_type $sVideoPath 視訊絕對路徑
* @param unknown_type $sThumbPath 縮圖儲存路徑,相對路徑
* @param unknown_type $sThumbFileName 縮圖名稱
* @param unknown_type $sTime 截圖時間
*/
public static function videoThumb($sVideoPath,$sThumbPath,$sThumbFileName='',$sTime = '00:00:01'){
//校驗檔案是否存在
if(!self::_checkPath($sVideoPath)){
return false;
}
//校驗副檔名
$extension = self::_getExtension($sVideoPath);
/*if(!in_array($extension, self::$videoArr)){
return false;
}*/
//$sThumbPath = '/upload/bosapi/img/';
if (!self::_checkPath(public_path().$sThumbPath)) {
mkdirs(public_path().$sThumbPath);
}
//$sThumbFileName = date('YmdHis').'_'.rand(1000,9999).'.jpg';
$s = " /usr/local/bin/ffmpeg -ss ".$sTime." -i ".$sVideoPath." ".public_path().$sThumbPath.$sThumbFileName." -r 1 -vframes 1 -an -vcodec mjpeg ";
exec($s);
if(self::_checkPath(public_path().$sThumbPath.$sThumbFileName)){
return $sThumbPath.$sThumbFileName;
}else{
return false;
}
}
protected static function _checkPath($path = NULL){
if(empty($path)){
return FALSE;
}
if(file_exists($path)){
return TRUE;
}else {
return FALSE;
}
}
protected static function _getExtension($file){
return pathinfo($file, PATHINFO_EXTENSION);
}
/**
* 視訊轉碼
* @param unknown_type $file 原路徑,絕對路徑
* @param unknown_type $targetFilePath 目標路徑,相對路徑
* @param unknown_type $targetFileName 目標名稱
*/
public function converToMp4($file,$targetFilePath,$targetFileName){
if (!$file || !$targetFileName || !self::_checkPath($file) ){
return false;
}
$s = "/usr/local/bin/ffmpeg -i ".$file." ".public_path().$targetFilePath.$targetFileName;
exec($s);
if(self::_checkPath(public_path().$targetFilePath.$targetFileName)){
return $targetFilePath.$targetFileName;
}else{
return false;
}
}
}
“`