Blog スタッフブログ

PHP システム開発

[PHP]動画変換を行い進捗のパーセンテージを取得する

システム開発担当のTFです。

やり方

  • ffprobe をpopen で実行し、duration を取得する( 動画の全再生時間 )
  • ffmpeg をpopen で実行し、time を取得する( 動画の変換中の現在地点の再生時間 )
  • durationとtimeから進捗のパーセンテージを算出する

サンプル

<?php

$src_file_path = "元の動画ファイルのパス";
$dest_file_path = "変換先の動画ファイルのパス";

// duration( 動画の全再生時間 ) の取得
$duration = getDuration($src_file_path);

// 動画の変換
convertMovie($src_file_path, $dest_file_path, $duration);



function getDuration($src_file_path)
{
	// durationの取得
	$command = 'ffprobe "'.$$src_file_path.'" -hide_banner -show_entries format=duration';

	$handle = popen($command,'r');
	$duration = 0;

	while(!feof($handle)) {

		// 改行コードが環境により異なることがあるので注意
		$log = stream_get_line($handle,1024,"\r");
		
		/*
		$log の中身 が、このような形で取れる
		[FORMAT]
		duration=888.488005
		[/FORMAT]
		*/
		
		// durationを抜き出す
		if( preg_match('/[0-9]+(\.[0-9]*)?/', $log, $match) == 1 ){
			$duration = $match[0];
			break;
		}
	}

	pclose($handle);
	
	return $duration;

}

function convertMovie($src_file_path, $dest_file_path, $duration)
{
	$command = 'ffmpeg -i "'.$src_file_path .'" 変換のパラメータ "'. $dest_file_path. '"  2>&1';
	
	$handle = popen($command,'r');
	
	while(!feof($handle)) {

		// 改行コードが環境により異なることがあるので注意
		$log = stream_get_line($handle,1024,"\r");
		
		/*
			前後に、詳細情報が入った後、
			frame=    0 fps=0.0 q=0.0 size=       0kB time=00:00:00.20 bitrate=   1.8kbits/s speed=7.92x    
			の形の変換状態が取れるため、そこからtimeを取得する
		*/

		// time= の取得
		if( preg_match('/time=[0-9]+:[0-9]+:[0-9]+(\.[0-9]*)?/', $log, $match) == 1 ){
			
			$time = $match[0];
			
			$time = str_replace('time=', '', $time);
			
			// 時間表記を秒にする
			$seconds = timeToSeconds($time);

			// 進捗のパーセンテージを算出
			$progress = (int)($seconds / $duration * 100);
			
			// 進捗の保存等
		}

	}
	
	pclose($handle);
	
	$progress = 100;
}

// タイムから秒への変換
function timeToSeconds($time)
{
	$seconds = 0;
	
	$arr = explode(':', $time);
	
	if( !empty($arr[0]) ){
		$seconds += $arr[0] * 60 * 60;
	}
	if( !empty($arr[1]) ){
		$seconds += $arr[1] * 60;
	}
	if( !empty($arr[2]) ){
		$seconds += $arr[2];
	}
	
	return $seconds;
}

	
?>