X-Git-Url: http://p2p-next.cs.pub.ro/gitweb/?a=blobdiff_plain;f=application%2Fhelpers%2Fvideo_helper.php;h=aa7c3841c2dd8469234a50c2ef9e7e61bfa84d0a;hb=HEAD;hp=64efee576f7a433fb1daf85584e8aa69d18b5162;hpb=211dc651c32bb8998b3eb2fdd3a3b85fc31921ec;p=living-lab-site.git diff --git a/application/helpers/video_helper.php b/application/helpers/video_helper.php index 64efee5..aa7c384 100644 --- a/application/helpers/video_helper.php +++ b/application/helpers/video_helper.php @@ -100,5 +100,190 @@ function get_closest_res($haystack, $needle, $access_function = NULL) return $i_min; } +/** + * "Private" function used by get_av_info which returns the value from a + * "key=value" formatted string. + * + * @param string $str_key_value a string formatted as key=value + * @return string + */ +function _parse_value($str_key_value) +{ + return trim(substr( + $str_key_value, + strpos($str_key_value, '=') + 1, + strlen($str_key_value) + )); +} + +/** + * Formats the floating number of seconds to a string with format [HH:]mm:ss . + * + * @param float $secs + * @return string + */ +function format_duration($secs) +{ + $secs = intval(round($secs)); + + $h = intval(floor($secs / 3600)); + $m = intval(floor(($secs % 3600) / 60)); + $s = $secs % 3600 % 60; + + $duration = sprintf('%02d', $m) . ':' . sprintf('%02d', $s); + + if ($h > 0) + return sprintf('%02d', $h) . ':' . $duration; + + return $duration; +} + +/** + * Returns information about an Audio/Video file. + * + * @param string $file_name Audio/Video file + * @return dictionary FALSE on error or a dictionary of audio/video properties + * with the following keys otherwise: + * + */ +function get_av_info($file_name) +{ + $h = popen('ffprobe -show_streams -show_format "' + . $file_name . '" 2> /dev/null', 'r'); + + $tag = NULL; + $codec_type = NULL; + + while ( ($r = fgets($h, 512)) !== FALSE) + { + // Match tags. + if (preg_match('/^\[FORMAT\]/', $r)) + { + $tag = 'FORMAT'; + continue; + } + if (preg_match('/^\[STREAM\]/', $r)) + { + $tag = 'STREAM'; + continue; + } + + if ($tag == 'FORMAT') + { + // Size + if (preg_match('/^size=/', $r)) + $size = intval(_parse_value ($r)); + } + + if ($tag == 'STREAM') + { + // Width + if (preg_match('/^width=/', $r)) + $width = intval(_parse_value($r)); + + // Height + if (preg_match('/^height=/', $r)) + $height = intval(_parse_value($r)); + + // DAR + if (preg_match('/^display_aspect_ratio=/', $r)) + $dar = _parse_value($r); + + // Codec Type + if (preg_match('/^codec_type=/', $r)) + $codec_type = _parse_value($r); + + // Duration + if (preg_match('/^duration=/', $r) + && strcmp($codec_type, 'video') == 0) + $duration = format_duration(floatval(_parse_value($r))); + } + } + + if (pclose($h) > 0) + return FALSE; + + return array('width'=>$width, 'height'=>$height, 'dar'=>$dar, + 'duration'=>$duration, 'size'=>$size); + +// return array('width'=> 1440, 'height'=> 1080, 'dar'=> '16:9', +// 'duration'=> '00:10', 'size'=> 5568748); +} + +/** + * Return a dictionary with formats compliant for DB and CIS and computes + * resolutions such that an uploaded video will not be converted to a higher + * resolution. + * + * @param type $formats formats as in content_ingestion config file + * @param type $av_info structure as returned by get_av_info function from this + * helper + * @param type $elim_dupl_res eliminate consecutive formats with the same + * resolution + * @return array a dictionary with DB format at key 'db_formats' and CIS format + * at key 'transcode_configs' + */ +function prepare_formats($formats, $av_info, $elim_dupl_res=FALSE) +{ + $transcode_configs = array(); + $db_formats = array(); + + for ($i = 0; $i < count($formats); $i++) + { + $transcode_configs[$i]['container'] = $formats[$i]['container']; + $transcode_configs[$i]['extension'] = $formats[$i]['extension']; + $db_formats[$i]['ext'] = $formats[$i]['extension']; + $transcode_configs[$i]['a_codec'] = $formats[$i]['audio_codec']; + $transcode_configs[$i]['a_bitrate'] = $formats[$i]['audio_bit_rate']; + $transcode_configs[$i]['a_samplingrate'] = $formats[$i]['audio_sampling_rate']; + $transcode_configs[$i]['a_channels'] = $formats[$i]['audio_channels']; + $transcode_configs[$i]['v_codec'] = $formats[$i]['video_codec']; + $transcode_configs[$i]['v_bitrate'] = $formats[$i]['video_bit_rate']; + $transcode_configs[$i]['v_framerate'] = $formats[$i]['video_frame_rate']; + $transcode_configs[$i]['v_dar'] = $av_info['dar']; + $db_formats[$i]['dar'] = $av_info['dar']; + + $sar = $av_info['width'] / $av_info['height']; + + if ($av_info['height'] < $formats[$i]['video_height']) + { + $width = $av_info['width']; + $height = $av_info['height']; + } + else + { + $height = $formats[$i]['video_height']; + $width = round($sar * $height); + } + + $transcode_configs[$i]['v_resolution'] = "${width}x${height}"; + $db_formats[$i]['res'] = "${width}x${height}"; + } + + // Eliminate formats with duplicate resolutions. +// if ($elim_dupl_res) +// { +// for ($i = 1; $i < count($transcode_configs); $i++) +// { +// if ($transcode_configs[$i]['v_resolution'] +// === $transcode_configs[$i - 1]['v_resolution']) +// { +// unset($transcode_configs[$i - 1]); +// unset($db_formats[$i - 1]); +// $i--; +// } +// } +// } + + return array('transcode_configs'=>$transcode_configs, + 'db_formats'=>$db_formats); +} + /* End of file video_helper.php */ /* Location: ./application/helpers/video_helper.php */ \ No newline at end of file