How to get Highest possible bit rate and dimensions of a video? - php

I am using a package called pascalbaljetmedia/laravel-ffmpeg
And want to create an HLS playlist for video streaming.
but first i want to check the video bit-rate or width/height to see if it's a 4k, 1080, 720 etc.
So how do i calculate the video bitrate and it's dimensions?..
Here is what i want to do after getting the video information:
$video = FFMpeg::fromDisk('videos')
->open('original_video.mp4')
->exportForHLS();
$resolutions = [];
//check if we can make 4k version
if ( ( $bitrate >= 14000 ) || ( $width >= 3840 && $height >= 2160 ) )
{
// Then it's a 4k video
// We make a 4k version of HLS
$resolutions[] = ['q' => 14000, 'size' => [ 'w' => 3840, 'h' => 2160]];
}
//check if we can make HD version
if( ( $bitrate >= 5800 ) || ( $width >= 1920 && $height >= 1080 ) )
{
// Then it's a HD video
// We make a HD version of HLS
$resolutions[] = ['q' => 5800, 'size' => [ 'w' => 1920, 'h' => 1080]];
}
//Lastly we loop through and add formarts
foreach($resolutions as $resolution){
$video->addFormat($resolution['q'], function($media) {
$media->addFilter('scale='. $resolution['size']['w].':'. $resolution['size']['h]);
});
}
$video->save('video_name.m3u8');
Any help?.

I don't use Laravel, but it looks like pascalbaljetmedia/laravel-ffmpeg is a wrapper for php-ffmpeg/php-ffmpeg, so you should be able to use FFProbe to extract this information.
$ffprobe = FFMpeg\FFProbe::create();
$video = $ffprobe->streams('original_video.mp4')->videos()->first();
$width = $video->get('width');
$height = $video->get('height');
$bitrate = $video->get('bit_rate');
Incidentally, there are a couple of typos in your line of code which should be $media->addFilter('scale=' . $resolution['size']['w'] . ':' . $resolution['size']['h']);.

Related

Can PHPword show Pie Chart in percenage with two decimals?

I use PHPword class to create Word file in PHP.
Can you create Pie chart to show value in percentage with two decimals?
$c3 = array('Expensive kW', 'Cheap kW');
$s3 = array($expensive, $cheap);
$tablePie2Charts = $section->addTable('Chart');
$tablePie2Charts->addRow();
$stylePie2Chart = array(
'width' => Converter::inchToEmu(5),
'height' => Converter::inchToEmu(3),
'valueAxisTitle' => 'Last month consumed in kW',
'showLegend' => true,
'dataLabelOptions' => array(
'showCatName' => false,
'showVal' => false,
'showPercent' => true
)
);
$c1 = $tablePie2Charts->addCell()->addChart('pie', $c3, $s3, $stylePie2Chart);
I also encountered the same problem.But i can't find an api to support it.
And here my solution:
edit the file /PhpOffice/Phpword/Writer/Word2007/Part/Chart.php
near the line 250. Insert the code
$xmlWriter->writeElementBlock("c:numFmt",['formatCode'=>'0.00%','sourceLinked'=>'0']);
between
$xmlWriter->startElement('c:dLbls');
and
foreach ($style->getDataLabelOptions() as $option => $val) {
It finally look like that:
$xmlWriter->startElement('c:dLbls');
$xmlWriter->writeElementBlock("c:numFmt",['formatCode'=>'0.00%','sourceLinked'=>'0']);
foreach ($style->getDataLabelOptions() as $option => $val)
if you just want it in pie chart and you should:
if ('pie' === $this->element->getType()){
$xmlWriter->writeElementBlock("c:numFmt",['formatCode'=>'0.00%','sourceLinked'=>'0']);
}
You can change the formatCode like 0.0% 0.00% 0.000% whatever you want.
If someone find the better way,plz tell me,thanks.

Converting 8 Bit Images to 16 bit with Php ImageMagick

What I'm trying to do is convert an 8 bit image to a 16 bit image using php ImageMagick. With Imagick it's as easy as convert /location/image.jpg -colors 8 -depth 16 txt:-. In the PHP docs it shows that you can do it using $imagick->setImageDepth(16); but the problem is that it doesn't give you the 16 bit hex / rgb numbers.
Is there an advantage to using 16 bit when trying to extract colors from an image? If not then I'm wondering isn't the php function working?
Here is what I get from $mapColor->getColor():
Array
(
[r] => 51
[g] => 51
[b] => 51
[a] => 1
)
Array
Here is my code for getting colors:
// Create new instance
$imagick = new Imagick($image);
// Set number of colors
$numberColors = 6;
// Set colorspace
$colorSpace = Imagick::COLORSPACE_SRGB;
// Set tree depth
$treeDepth = 0;
// Set dither
$dither = false;
// Convert to 16 bit
$imagick->setImageDepth(16);
// Quantize image to number of colors
$imagick->quantizeImage($numberColors, $colorSpace, $treeDepth, $dither, false);
// Get Image Dimensions
$sizes = $imagick->getImageGeometry();
// Get image's histogram
$pixels = $imagick->getImageHistogram();
// Temp cache dimensions
$totalSize = $sizes['width'] * $sizes['height'];
// Loop through each pixel
foreach($pixels as $k => $v) {
// Get total number of color instances
$count = $v->getColorCount();
// Get colormap at pixel
$mapColor = $imagick->getImageColormapColor($k);
// Get colore
$rgbColor = $mapColor->getColor();
// Convert to RGB hex values
$red = str_pad(dechex($rgbColor['r']), 2, 0, STR_PAD_LEFT);
$green = str_pad(dechex($rgbColor['g']), 2, 0, STR_PAD_LEFT);
$blue = str_pad(dechex($rgbColor['b']), 2, 0, STR_PAD_LEFT);
// Set hexadecimal
$hex = $red.$green.$blue;
// Calculate color percentage
$percentage = (100 * $count) / $totalSize;
// Push colors into array
$colors[] = array(
'red' => $rgbColor['r'],
'green' => $rgbColor['g'],
'blue' => $rgbColor['b'],
'hex' => $hex,
'count' => $count,
'percentage' => $percentage,
);
}
print_r($colors);

Need a logic using foreach

I have a following table display
Task No. Person Company Project Task Date Tracked Total Time Comments
14.1 vaish, arpit ABC-TecHolding Relaunch Websitnalysis 2013-02-12 19:21:03
14.2 vaish, arpit Sugarion New Opensource Server 2013-02-12 19:21:03
14.6 vaish, arpit Sugarion New Opensource Server 2013-02-12 19:21:03
5.26 Projectmanager, Paul ABC-Tec Holding Relaunch Website 2010-03-13 03:40:16
5.27 Projectmanager, Paul ABC-Tec Holding Relaunch Website 2010-03-12 03:40:16
5.27 Projectmanager, Paul ABC-Tec Holding Relaunch Website 2010-03-13 03:40:16
8.2 Worker, Willi Customers ACME Hosting Data transfer 2010-03-13 00:21:18
14.2 Worker, Willi Sugarion New Opensource Server 2013-02-06 00:21:18 fyhbvghjukjjkhhlhh uuiuijujj jookljh
This is my foreach loop
foreach($result123 as $key=>$task) {
$time=$this->addtime($task['name'],$range['start'],$range['end']); //to calculate total time per user in time range
$diff = $task['estimated']+$task['tracked'];
$diffSign = $diff > 0 ? '-' : '+';
$table->addRow(array(
'number' => $task['tasknumber'].' '.$task['id_project'] ,
'person'=> $task['name'],
'customer' => $task['company'],
'project' => $task['project'],
'task' => $task['task'],
'date' => $task['date_tracked'],
'tracked' => $task['workload_tracked'],
'Total_Time' => $time,
'comment'=>$task['comment']
));
}
The column total time shows total of time tracked per person.
I want the total time should show only once per Person and not display again and again for each row.
Thanks in advance.
That's how I'd do it (Pseudocode) :
Set an array of "checked" people
Foreach record :
Is person in the "checked" array?
If yes, go on.
If no, display total AND add person to "checked" people.
And in PHP : (if I got it right)
$checked = array();
foreach($result123 as $key=>&$task) {
$time=$this->addtime($task['name'],$range['start'],$range['end']); //to calculate total time per user in time range
$diff = $task['estimated']+$task['tracked'];
$diffSign = $diff > 0 ? '-' : '+';
if (in_array($task['name'],$checked) $time =0;
else {
$checked[] = $task['name'];
}
$table->addRow(array(
'number' => $task['tasknumber'].' '.$task['id_project'] ,
'person'=> $task['name'],
'customer' => $task['company'],
'project' => $task['project'],
'task' => $task['task'],
'date' => $task['date_tracked'],
'tracked' => $task['workload_tracked'],
'Total_Time' => $time,
'comment'=>$task['comment']
));
}
$name = '';
foreach($result123 as $key=>$task) {
if ($name == $task['name']) {
$time = '';
}
elseif ($name != $task['name']) {
$time=$this->addtime($task['name'],$range['start'],$range['end']);
$name = $task['name'];
}
$diff= $task['estimated']+$task['tracked'];
$diffSign= $diff > 0 ? '-' : '+';
$table->addRow(array(
'number' => $task['tasknumber'].' '.$task['id_project'] ,
'person'=> $task['name'],
'customer' => $task['company'],
'project' => $task['project'],
'task' => $task['task'],
'date' => $task['date_tracked'],
'tracked' => $task['workload_tracked'],
'Total_Time' => $time,
'comment'=>$task['comment']
));
}
That should do it, I think.

PhotosDuplicateTagInBatch error when uploading / tagging photos in Facebook!

I am writing an application that allows users to upload multiple photos at once to facebook and it will automatically tag themselves (no one else) in the photo when this happens.
If I run the script once, it works fine, if I try to upload and tag multiple photos then it complains with a PhotosDuplicateTagInBatch error and I can't find ANY information as to why this is happening!
Here is my code:
for ($i = 5; $i >= 1; $i--)
{
$img = GetImage($i);
$tag = array(
'tag_uid' => $facebook->getUser(),
'x' => rand (0,100),
'y' => rand (0,100)
);
$tags[] = json_encode($tag);
$args = array(
'message' => $i,
'image' => '#'.realpath($img),
'tags' => $tags,
);
$data = $facebook->api('/me/photos', 'post', $args);
}
}
If I output my arguments they come out as:
Code:
Array
(
[message] => 4
[image] => #imagepathhere
[tags] => Array
(
[0] => {"tag_uid":"100002493436028","x":13,"y":68}
[1] => {"tag_uid":"100002493436028","x":60,"y":57}
)
)
So essentially, from what I can tell, you cannot upload and tag multiple photos like this. What I had to do was upload the photo, then tag it separately and rinse and repeat

banner rotator advertising with probability

I have banners advertising with number of views, like CPM system.
And for example :
i have 3 banner:
banner1 with 20.000 nr of views
banner2 with 10.000 nr of views
banner3 with 5.000 nr of views
and on my website the banner must to appear in this position (when the page is reloaded) :
banner1 banner2 banner1 banner2 banner3
if the number of views is higher then the probability of apparition is higher
how can i do this in php?
First of all, your system is just... stupid. It perpetuates banners with lots of views while newly created banners with 0 or few views will never get a chance to be picked and thus will never be actually seen...
That being said, if you have an array that looks like this:
$banners = array
(
'banner1' => 1,
'banner2' => 2,
'banner3' => 4,
'banner4' => 8,
'banner5' => 16,
);
You can use a function like this one to weightily pick one banner:
function Probability($data)
{
if (is_array($data) === true) {
$result = 0;
$probability = mt_rand(1, array_sum($data));
foreach ($data as $key => $value) {
$result += $value;
if ($result >= $probability) {
return $key;
}
}
}
return false;
}
Usage (test it # CodePad.org or # IDEOne):
echo Probability($banners); // banner5
Sample from 100 executions:
Array
(
[banner5] => 41
[banner4] => 38
[banner3] => 10
[banner2] => 8
[banner1] => 3
)
Here's a php way to do it
I'm imagining your array will look something like this...
$banners = array(
array (
'name' => 'banner1',
'views' => 20
),
array (
'name' => 'banner2',
'views' => 10
),
array (
'name' => 'banner3',
'views' => 5
)
);
This function basically loops through the banners and however many views a banner has, that many items of its array index are added to an array. Then a random one is chosen. Items with more views have a better chance of being chosen.
function getWeightedRandom( $array ) {
$universe_array = array();
foreach ( $array as $k => $b ) {
$universe += $b['views'];
$universe_array = array_pad( $universe_array, $universe, $k );
}
$rand = mt_rand( 0, count( $universe_array ) -1 );
return $array[ $universe_array[ $rand ] ];
}
$r = getWeightedRandom($banners);
print_r($r);
A simple mysql option is:
select * from banners order by rand() * views desc limit 1
banners with more views will have a higher chance of being the top result

Categories