how to parse m3u8 and get difffrent bitttrate sub m3u8 urls? - php

could any one show me how in php i can get different bitrate(resolution) sub m3u8 urls if we have the main playlist m3u8 using get_data method?The following is data i have from get_data method but i want to get m3u8 urls for each resolution. Could any one show me how this can be done?Thanks in advance.
$returned_content = get_data(''.$m3u8Url);
/* gets the data from a URL */
function get_data($url) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
main playlist m3u8:
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1628000,RESOLUTION=852x480,CODECS="avc1.77.30,mp4a.40.2"
http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/erewewrwrtf34324343443243434344/test1.mpegts/playlist-dfasdfasdfaw4q3243241.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=128000,RESOLUTION=256x144,CODECS="avc1.66.30,mp4a.40.2"
http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/fgdhgfhgjhghfdsdf45454545345435/test1.mpegts/playlist-adfdfghgjdt5t45454542.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=464000,RESOLUTION=426x240,CODECS="avc1.77.30,mp4a.40.2"
http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/764563564565445fsdf4r3dfdfdffdf/test1.mpegts/playlist-eertyeryry564534rrtr3.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=828000,RESOLUTION=640x360,CODECS="avc1.77.30,mp4a.40.2"
http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/fgsfdgdfgfdg5435345456745264554/test1.mpegts/playlist-fgsfghdghjt4353454544.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2128000,RESOLUTION=1024x576,CODECS="avc1.77.30,mp4a.40.2"
http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/sfdgsdfgfdgfdgfdgfd465436546576/test1.mpegts/playlist-fghdjhygjujdfgsaf4455.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=3692000,RESOLUTION=1280x720,CODECS="avc1.64001f,mp4a.40.2"
http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/sfdghgjyuktyurty546565466453645/test1.mpegts/playlist-safdghhgfjjyj45345546.m3u8

First off, you need to get data source, then process them (explode() the values, as your sample data is in line breaks), then group them by two's, and in the end loop them. Consider this example:
<?php
$curl_output = '#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1628000,RESOLUTION=852x480,CODECS="avc1.77.30,mp4a.40.2"
http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/erewewrwrtf34324343443243434344/test1.mpegts/playlist-dfasdfasdfaw4q3243241.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=128000,RESOLUTION=256x144,CODECS="avc1.66.30,mp4a.40.2"
http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/fgdhgfhgjhghfdsdf45454545345435/test1.mpegts/playlist-adfdfghgjdt5t45454542.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=464000,RESOLUTION=426x240,CODECS="avc1.77.30,mp4a.40.2"
http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/764563564565445fsdf4r3dfdfdffdf/test1.mpegts/playlist-eertyeryry564534rrtr3.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=828000,RESOLUTION=640x360,CODECS="avc1.77.30,mp4a.40.2"
http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/fgsfdgdfgfdg5435345456745264554/test1.mpegts/playlist-fgsfghdghjt4353454544.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2128000,RESOLUTION=1024x576,CODECS="avc1.77.30,mp4a.40.2"
http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/sfdgsdfgfdgfdgfdgfd465436546576/test1.mpegts/playlist-fghdjhygjujdfgsaf4455.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=3692000,RESOLUTION=1280x720,CODECS="avc1.64001f,mp4a.40.2"
http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/sfdghgjyuktyurty546565466453645/test1.mpegts/playlist-safdghhgfjjyj45345546.m3u8';
// process the string
$pieces = explode("\n", $curl_output); // make an array out of curl return value
unset($pieces[0]); // remove #EXTM3U
$pieces = array_map('trim', $pieces); // remove unnecessary space
$pieces = array_chunk($pieces, 2); // group them by two's
?>
Formatted pieces should look something like this:
Array
(
[0] => Array
(
[0] => #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1628000,RESOLUTION=852x480,CODECS="avc1.77.30,mp4a.40.2"
[1] => http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/erewewrwrtf34324343443243434344/test1.mpegts/playlist-dfasdfasdfaw4q3243241.m3u8
)
[1] => Array
(
[0] => #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=128000,RESOLUTION=256x144,CODECS="avc1.66.30,mp4a.40.2"
[1] => http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/fgdhgfhgjhghfdsdf45454545345435/test1.mpegts/playlist-adfdfghgjdt5t45454542.m3u8
)
...
Then, on the html loop and them, and inside the loop process the links:
<?php foreach($pieces as $key => $value): ?>
<a href="<?php echo $value[1]; ?>">Watch this in
<?php
$value[0] = explode(',', $value[0]);
foreach($value[0] as $index => $element) {
if(stripos($element, 'RESOLUTION') !== false) {
echo $element;
}
}
?>
</a><br/>
<?php endforeach; ?>
The HTML Markup should now look something like this:
<a href="http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/erewewrwrtf34324343443243434344/test1.mpegts/playlist-dfasdfasdfaw4q3243241.m3u8">Watch this in
RESOLUTION=852x480 </a>
<a href="http://me.mysite.com/media/l3/ertetertyrtut34534234324f3esrere/fgdhgfhgjhghfdsdf45454545345435/test1.mpegts/playlist-adfdfghgjdt5t45454542.m3u8">Watch this in
RESOLUTION=256x144 </a>

If I understood the quetion right you need to parse a string and get resolution.
function findResolution($string){
$array = explode(",",$string);
foreach ($array as $item){
if (strpos($item,"RESOLUTION")!==false){
return str_replace("RESOLUTION=","",$item);
}
}
}

Why not fopen/fgets?
function parseHLS($file) {
$return = array();
$i = 0;
$handle = fopen($file, "r");
if($handle) {
while(($line = fgets($handle)) !== FALSE) {
if(strpos($line,"EXT-X-STREAM-INF") !== FALSE) {
if ($c=preg_match_all ("/.*?(BANDWIDTH)(.*?)(,)(RESOLUTION)(.*?)(,)/is", $line, $matches)) {
$return['data'][$i]['bandwidth'] = str_replace("=","",$matches[2][0]);
$return['data'][$i]['resolution'] = str_replace("=","",$matches[5][0]);
}
}
if(strpos($line,".ts") !== FALSE) {
$return['data'][$i]['url'] = str_replace(array("\r","\n"),"",$line);
$i++;
}
}
fclose($handle);
}
return $return;
}
That gets you an array with bandwidth, resolution and url keys for each iteration in the original file.

Related

How to get data for specific condtion in php curl

'url here' which contains a data key and the value is a string which contains items in the format: key=STRING, age=INTEGER. My goal is to count how many items exist that have an age equal to or greater than 50, and print this final value.
$ch = curl_init('url here');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
$data = curl_exec($ch);
curl_close($ch);
print_r(json_decode($data, true));
$data getting data as follows:
Array
(
[data] => key=IAfpK, age=58,
key=WNVdi, age=64,
key=jp9zt, age=47,
key=0Sr4C, age=68,
key=CGEqo, age=76,
key=IxKVQ, age=79, key=eD221, age=29, key=XZbHV, age=32, key=k1SN5, age=88, key=4SCsU, age=65, key=q3kG6, age=33, key=MGQpf, age=13, key=Kj6xW, age=14, key=tg2VM, age=30, key=WSnCU, age=24, key=f1Vvz, age=46, key=dOS7A, age=72, key=tDojg, age=82, key=nZyJA, age=48, key=R8JTk, age=29, key=005Ot, age=66, key=HHROm, age=12, key=5yzG8, age=51, key=xMJ5D, age=38, key=TXtVu, age=82, key=Hz38B, age=84, key=WfObU, age=27, key=mmqYB, age=14, key=4Z3Ay, age=62, key=x3B0i, age=55, key=QCiQB, age=72, key=zGtmR, age=66, key=nlIN9, age=8, key=hKalB, age=50, key=Na33O, age=17, key=jMeXm, age=15, key=OO2Mc, age=32, key=hhowx, age=32 )
Not getting how to match value and get count.
Example Input
{"data":"key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47"}
Example Output
2
If anyone have idea then please let me know
I originally missed the over 50 part.
If your goal is to just count, and your data is as uniform as you say, you can still just search on age= followed by one or more digits using RegEx, then count the over 50 items:
$data = 'key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47';
$itemsOverFifty = [];
if(preg_match_all('/age=(?<age>\d+)/', $data, $matches)) {
$itemsOverFifty = array_filter($matches['age'], fn($item) => $item >= 50 );
}
echo count($itemsOverFifty);
Demo: https://3v4l.org/8eqnR
This is rather messy and a REGEX person may be able to clean this up a bit, but it seems to work
function fixTheNonsenseJson($nonsense)
{
$a = json_decode($nonsense);
$s = str_replace( ['key=', ', age=', ', "key'], ['"key":"', '","age":"', '", "key'], $a->data);
$bits = explode(',', $s);
$usable = [];
foreach ($bits as $bit) {
$j = json_decode('{' . $bit. '}');
if ( isset($j->key) ) {
$t = new stdClass();
$t->key = $j->key;
}
if ( isset($j->age) ) {
$t->age = $j->age;
$usable[] = $t;
$t = null;
}
}
return $usable;
}
$badJson = '{"data" : "key=IAfpK, age=58, key=WNVdi, age=64, key=jp9zt, age=47, key=0Sr4C, age=68, key=CGEqo, age=76, key=IxKVQ, age=79, key=eD221, age=29, key=XZbHV, age=32, key=k1SN5, age=88, key=4SCsU, age=65, key=q3kG6, age=33, key=MGQpf, age=13, key=Kj6xW, age=14, key=tg2VM, age=30, key=WSnCU, age=24, key=f1Vvz, age=46, key=dOS7A, age=72, key=tDojg, age=82, key=nZyJA, age=48, key=R8JTk, age=29, key=005Ot, age=66, key=HHROm, age=12, key=5yzG8, age=51, key=xMJ5D, age=38, key=TXtVu, age=82, key=Hz38B, age=84, key=WfObU, age=27, key=mmqYB, age=14, key=4Z3Ay, age=62, key=x3B0i, age=55, key=QCiQB, age=72, key=zGtmR, age=66, key=nlIN9, age=8, key=hKalB, age=50, key=Na33O, age=17, key=jMeXm, age=15, key=OO2Mc, age=32, key=hhowx, age=32"}';
$usable = fixTheNonsenseJson($badJson);
// the actual code to do the count
$count = 0;
foreach( $usable as $u){
if ( $u->age > 50 ) {
$count++;
}
}
echo "Count > 50 = $count";

parse_str only returning first parameter

So I wrote some code that should simply take this
title=title&description=description&image=(some image here)&color=ff0000
And return this
echo $meta["title"] //title
echo $meta["description"] //description
echo $meta["image"] //(some image here)
echo $meta["color"] //ff0000
Instead, it only returns title for some reason...
<?php
$url = $_SERVER["REQUEST_URI"];
$url = substr($url, 2);
$url = base64_decode($url);
// title=title&description=description&image=(some image here)&color=ff0000
// confusing part
parse_str($url, $meta);
?>
What about smth like this?
$string = 'title=title&description=description&image=(some image here)&color=ff0000';
$array = explode("&", $string);
$finalArray = [];
foreach ($array as $arr) {
$singleArr = explode("=",$arr);
$finalArray[$singleArr[0]] = $singleArr[1];
}
print("<pre>".print_r($finalArray,true)."</pre>");
Which will print out:
Array
(
[title] => title
[description] => description
[image] => (some image here)
[color] => ff0000
)
Instead of reinventing the wheel :) (thx #u_mulder)
$urlString = parse_url($string, PHP_URL_QUERY);
parse_str($urlString, $urlArray);
print_r($urlArray["image"]); // Or what ever paramneter, like
foreach($urlArray as $key => $value) {
echo $urlArray[$key];
}

Show only a specific part of html response in php

I am trying to get tracking information from amazon using provided url
https://www.amazon.co.uk/progress-tracker/package/ref=pe_3187911_189395841_TE_typ?_encoding=UTF8&from=gp&itemId=&orderId=203-2171364-3066749&packageIndex=0&shipmentId=23796758607302
I am getting response using file_get_contents() function in php,
what I want is to show only that part of the response which contains the tracking information as an output of my php script and eliminate/hide all the unnecessary content from file_get_contents() response.
One way to do what you're looking for is use DomDocument to filter out the json data in the source ($file) and then use a recursive function to get the elements you need.
You can set the elements you need using an array, $filter. In this example we've taken a sample of some of the available data, i.e. :
$filter = [
'orderId', 'shortStatus', 'promiseMessage',
'lastTransitionPercentComplete', 'lastReachedMilestone', 'shipmentId',
];
The code
<?php
$filename = 'https://www.amazon.co.uk/progress-tracker/package/ref=pe_3187911_189395841_TE_typ?_encoding=UTF8&from=gp&itemId=&orderId=203-2171364-3066749&packageIndex=0&shipmentId=23796758607302';
$file = file_get_contents($filename);
$trackingData = []; // store for order tracking data
$html = new DOMDocument();
#$html->loadHTML($file);
foreach ($html->getElementsByTagName('script') as $a) {
$data = $a->textContent;
if (stripos($data, 'shortStatus') !== false) {
$trackingData = json_decode($data, true);
break;
}
}
// set the items we need
$filter = [
'orderId', 'shortStatus', 'promiseMessage',
'lastTransitionPercentComplete', 'lastReachedMilestone', 'shipmentId',
];
// invoke recursive function to pick up the data items specified in $filter
$result = getTrackingData($filter, $trackingData);
echo '<pre>';
print_r($result);
echo '</pre>';
function getTrackingData(array $filter, array $data, array &$result = []) {
foreach($data as $key => $value) {
if(is_array($value)) {
getTrackingData($filter, $value, $result);
} else {
foreach($filter as $item) {
if($item === $key) {
$result[$key] = $value;
}
}
}
}
return $result;
}
Output:
Array
(
[orderId] => 203-2171364-3066749
[shortStatus] => IN_TRANSIT
[promiseMessage] => Arriving tomorrow by 9 PM
[lastTransitionPercentComplete] => 92
[lastReachedMilestone] => SHIPPED
[shipmentId] => 23796758607302
)
Try this
<?php
$filename = 'https://www.amazon.co.uk/progress-tracker/package/ref=pe_3187911_189395841_TE_typ?_encoding=UTF8&from=gp&itemId=&orderId=203-2171364-3066749&packageIndex=0&shipmentId=23796758607302';
$file = file_get_contents($filename);
$html = new DOMDocument();
#$html->loadHTML($file);
foreach($html->getElementsByTagName('span') as $a) {
$property=$a->getAttribute('id');
if (strpos($property , "primaryStatus"))
print_r($property);
}
?>
It should show "Arriving tomorrow by 9 PM" status.

How to get only id from url

I have thousands of urls which have ids i want to get only ids from url for example
This is my array
Array
(
[0] => http://www.videoweed.es/file/f62f2bc536bad
[1] => http://www.movshare.net/video/5966fcb2605b9
[2] => http://www.nowvideo.sx/video/524aaacbd6614
[3] => http://vodlocker.com/pbz4sr6elxmo
)
I want ids from above links
f62f2bc536bad
5966fcb2605b9
524aaacbd6614
pbz4sr6elxmo
I have use parse_url function but its return me path which include all things after slash(/) like /file/pbz4sr6elxmo
<?php
foreach($alllinks as $url){
$parse = parse_url($url);
echo $parse['path'];
}
?>
Output
/pbz4sr6elxmo
/video/5966fcb2605b9
/file/f62f2bc536bad
/video/524aaacbd6614
You can try with explode -
$alllinks = array
(
'http://www.videoweed.es/file/f62f2bc536bad',
'http://www.movshare.net/video/5966fcb2605b9',
'http://www.nowvideo.sx/video/524aaacbd6614',
'http://vodlocker.com/pbz4sr6elxmo'
);
foreach($alllinks as $url){
$temp = explode('/', $url);
echo $temp[count($temp) - 1].'<br/>';
}
Output
f62f2bc536bad
5966fcb2605b9
524aaacbd6614
pbz4sr6elxmo
This will only help if the the url structure is same, i.e. the last part is the id
If the URLs always ends with the id you can simply do
$url = 'http://www.videoweed.es/file/f62f2bc536bad';
$url_split = explode('/', $url);
$code = $url_split[count($url_split) - 1];
Try this:
$alllinks = array(
'http://www.videoweed.es/file/f62f2bc536bad',
'http://www.movshare.net/video/5966fcb2605b9',
'http://www.nowvideo.sx/video/524aaacbd6614',
'http://vodlocker.com/pbz4sr6elxmo'
);
foreach($alllinks as $url){
$parts = explode('/', $url);
echo end($parts).'<br/>';
}

creating dynamic array in php

I have following records in text file, need to extract that record form text file and treat them as seperate array variables
r1=(1,2,3)|r2=(4,5,6)|r3=(1,2,3,4,5,7)|rn=(9,6,7,8) seperated by pipe(|)
I need to represent that as array use seperately like below
$r1= Array
(
[0] => 1
[1] => 2
[2] => 3
)
$r2=Array
(
[0] => 4
[1] => 5
[2] => 6
)
I have no idea how to do it, is it possible in php?
Just a plain regular expression to break up the string, followed by an explode on each group:
if (preg_match_all('#(\w+)=\(([\d,]*)\)#', $s, $matches)) {
foreach ($matches[2] as $i => $groups) {
$group_name = $matches[1][$i];
$$group_name = array_map('intval', explode(',', $groups));
}
}
print_r($r1);
print_r($r3);
print_r($rn);
You can use Eval
//Assuming you can pull the content from text file using fread
$temp = "r1=(1,2,3)|r2=(4,5,6)";
$temp=str_replace("=","=array",$temp);
$split=explode("|",$temp);
echo "<pre>";
foreach($split as $k=>$v){
$v="$".$v.";";
//Evaluate a string as PHP code .i.e You will get r1,r2 as a variable now which is array
eval($v);
}
print_r($r1);
print_r($r2);
$data = "r1=(1,2,3)|r2=(4,5,6)|r3=(1,2,3,4,5,7)|rn=(9,6,7,8)";
$arr = explode("|", $data);
$finArray = array();
foreach($arr as $key=>$value)
{
$single = explode('(', $value);
$finArray[] = explode(',', str_replace(')', '', $single[1]));
}
print_r($finArray);
can be done as:
$string="r1=(1,2,3)|r2=(4,5,6)|r3=(1,2,3,4,5,7)|rn=(9,6,7,8)";
$string=str_repla("r1=","",$string);
$yourArray=explode('|', $string);
This code will help you:--
<?php
$file = "/tmp/file1.txt"; // this is your file path
$f = fopen($file, "r");
while ( $line = fgets($f, 1000) ) {
print $line;
$a=explode('|',$line);
print_r($a); // I have explode based on | for you...
foreach($a as $key=>$value)
{
print_r($value);
}
fclose($file);
}
?>
""or""
$a="r1=(1,2,3)|r2=(4,5,6)|r3=(1,2,3,4,5,7)|rn=(9,6,7,8)";
$a=explode('|',$a);
print_r($a);
<?php
$file = "file.txt";
$f = fopen($file, "r");
while ( $line = fgets($f, 1000) ) {
$str = $line;
}
$str1 = explode("|",$str);
foreach($str1 as $temp) {
$str2 = explode("=",$temp);
$data[$str2[0]] = explode(",",trim($str2[1],"()"));
}
echo '<pre>';
print_r($data);
echo '</pre>';
?>
This will do your job.

Categories