playtime_string

playtime_string

Postby Lenton » Sat Jul 09, 2011 11:19 am

For some reason [playtime_string] is only equalling '0:02' or '0:01' when the MP3s are clearly longer than that.

EDIT: It also seems that the [filesize] always equals '32768'.

Note: I am using the script that allows me to use MP3 files on remote servers:
viewtopic.php?f=3&t=1184
Lenton
User
 
Posts: 8
Joined: Fri Jul 08, 2011 9:14 am

Re: playtime_string

Postby James Heinrich » Sat Jul 09, 2011 3:09 pm

You're downloading 32kB of the file. Hence the file you're analyzing is 1 or 2 seconds long. MP3 file typically do not contain any kind of header that says how long they are in total, so the only way to calculate the playtime of a file is to divide the filesize by the average bitrate. If you need the full playtime you'll need to either copy the entire file locally, or possibly you could get away with copying the first 100kB or so and then padding the local temporary file to match the remote filesize (but depending on file contents you may get file corruption warnings). Ideally you should also grab the last 4kB or so and put it in the correct place to extract any relevant appended tags, if present (ID3v1, APE, Lyrics3).
James Heinrich
getID3() v1 developer
 
Posts: 1203
Joined: Fri May 04, 2001 11:00 am
Location: London, ON, Canada

Re: playtime_string

Postby Lenton » Tue Jul 12, 2011 4:42 am

What do I need to change in this:

Code: Select all
$filename = tempnam('/tmp','getid3');
if (file_put_contents($filename, file_get_contents('http://getid3.org/demo/test.mp3', false, null, 0, 32768))) {
   if (require_once('/path/to/getid3/getid3.php')) {
      $getID3 = new getID3;
      $ThisFileInfo = $getID3->analyze($filename);
      echo '<pre>'.print_r($ThisFileInfo, true).'</pre>';
   }
   unlink($filename);
}


to make it download the whole file?
Lenton
User
 
Posts: 8
Joined: Fri Jul 08, 2011 9:14 am

Re: playtime_string

Postby Pernod » Tue Jul 12, 2011 5:00 am

Lenton wrote:What do I need to change in this:

Code: Select all
$filename = tempnam('/tmp','getid3');
if (file_put_contents($filename, file_get_contents('http://getid3.org/demo/test.mp3'))) {
   if (require_once('/path/to/getid3/getid3.php')) {
      $getID3 = new getID3;
      $ThisFileInfo = $getID3->analyze($filename);
      echo '<pre>'.print_r($ThisFileInfo, true).'</pre>';
   }
   unlink($filename);
}


to make it download the whole file?

Remove all the arguments after file_get_contents as above. This will seriously slow down your analysis since you are downloading all the files and not caching them locally. Each time to re-run the script it will download them all again.
Pernod
getID3() contributor
 
Posts: 100
Joined: Sat Mar 21, 2009 12:30 pm
Location: London, UK

Re: playtime_string

Postby Windoves » Sun Jul 31, 2011 1:07 am

Code: Select all
<?php
$remoteFile = 'http://us.php.net/get/php-5.2.10.tar.bz2/from/this/mirror';
$ch = curl_init($remoteFile);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //not necessary unless the file redirects (like the PHP example we're using here)
$data = curl_exec($ch);
curl_close($ch);
if ($data === false) {
  echo 'cURL failed';
  exit;
}

$contentLength = 'unknown';
$status = 'unknown';
if (preg_match('/^HTTP\/1\.[01] (\d\d\d)/', $data, $matches)) {
  $status = (int)$matches[1];
}
if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {
  $contentLength = (int)$matches[1];
}

echo 'HTTP Status: ' . $status . "\n";
echo 'Content-Length: ' . $contentLength;
?>


I found this on the interwebz... The only problem for me is, how do I get the bit rate and calculate the playtime?
Windoves
User
 
Posts: 9
Joined: Sun Jul 03, 2011 1:22 am

Re: playtime_string

Postby James Heinrich » Sun Jul 31, 2011 6:21 am

Windoves wrote:I found this on the interwebz... The only problem for me is, how do I get the bit rate and calculate the playtime?
Your chunk of code is roughly equivalent to this in the above code examples:
Code: Select all
file_get_contents('http://getid3.org/demo/test.mp3')
-- it gets data from the remote file. True, it's more robust and returns more useful information on failure, but essentially just gets the contents of the remote file.
James Heinrich
getID3() v1 developer
 
Posts: 1203
Joined: Fri May 04, 2001 11:00 am
Location: London, ON, Canada

Re: playtime_string

Postby Windoves » Sun Jul 31, 2011 1:22 pm

Actually it gets just the headers, and not the actual "body" of the file. From this we can get the filesize without downloading the whole file.
Windoves
User
 
Posts: 9
Joined: Sun Jul 03, 2011 1:22 am

Re: playtime_string

Postby James Heinrich » Sun Jul 31, 2011 3:51 pm

Sorry, I didn't read the code closely.

But yes, you could use that to figure out the filesize of the remote file, grab a small chunk of the file (e.g. 32kB) and then pad out the temporary local file to match the filesize, and getID3 will probably report the correct playtime of the file, possibly with some corrupt data warnings. Be aware, however, that some MP3 files may have large ID3v2 tags at the front of the file and even downloading 1MB might be insufficient to even get to the start of the audio data (if there are a lot of embedded pictures, for example). Without parsing the ID3v2 header (which may or may not be present) to calculate the probable size of the ID3v2 tag, it's impossible to know how much data to grab.
James Heinrich
getID3() v1 developer
 
Posts: 1203
Joined: Fri May 04, 2001 11:00 am
Location: London, ON, Canada

Re: playtime_string

Postby Windoves » Sun Jul 31, 2011 9:41 pm

EDIT: FIXED, see post below
Last edited by Windoves on Mon Aug 01, 2011 1:35 am, edited 2 times in total.
Windoves
User
 
Posts: 9
Joined: Sun Jul 03, 2011 1:22 am

Re: playtime_string

Postby Windoves » Mon Aug 01, 2011 1:33 am

so I have made a patch for the playtime problem. Code is below:

Code: Select all
<?php

$url='http://getid3.org/demo/test.mp3'; // define the remote mp3 file

if($url){
$filename = tempnam('/tmp','getid3');
if (file_put_contents($filename, file_get_contents($url, false, null, 0, 300000))) {
   if (require_once('getid3/getid3.php')) {
      $getID3 = new getID3;
      $ThisFileInfo = $getID3->analyze($filename);
   }
   unlink($filename);
}
}

$bitratez=$ThisFileInfo[audio][bitrate]; // get the bitrate from the audio file

$headers = get_headers($url, 1); // Get the headers from the remote file
            if ((!array_key_exists("Content-Length", $headers))) { return false; } // Get the content length from the remote file
            $filesize= round($headers["Content-Length"]/1000); // Make the failesize into kilobytes & round it

$contentLengthKBITS=$filesize*8; // make kbytes into kbits
$bitrate=$bitratez/1000; //convert bits/sec to kbit/sec
$seconds=$contentLengthKBITS/$bitrate; // Calculate seconds in song

$playtime_mins = floor($seconds/60); // get the minutes of the playtime string
$playtime_secs = $seconds % 60; // get the seconds for the playtime string
if(strlen($playtime_secs)=='1'){$zero='0';} // if the string is a multiple of 10, we need to add a 0 for visual reasons
$playtime_secs = $zero.$playtime_secs; // add the zero if nessecary
$playtime_string=$playtime_mins.':'.$playtime_secs; // create the playtime string

echo $playtime_string;

?>

Windoves
User
 
Posts: 9
Joined: Sun Jul 03, 2011 1:22 am

Re: playtime_string

Postby Pernod » Mon Aug 01, 2011 7:40 am

Windoves wrote:so I have made a patch for the playtime problem. Code is below:

For your patch to be vaguely accurate you have to assume the following:
1. Bitrate is constant (not variable). Check $ThisFileInfo[audio][bitrate_mode] for 'CBR' or 'VBR'.
2. Your calculation assumes the whole file to be audio data, not accounting for id3 tags which could include 1000's bytes of image data.
Pernod
getID3() contributor
 
Posts: 100
Joined: Sat Mar 21, 2009 12:30 pm
Location: London, UK

Re: playtime_string

Postby Windoves » Mon Aug 01, 2011 12:26 pm

True, but when I excluded the headers length from the total file size from the files it gave me 4-7 seconds less than actual. This was made for MP3's primarily, and 300,000 bytes have been enough for all my files so far, including those with 2 embedded images that are 300x300px each. I'm sure someone will have use for this.
Windoves
User
 
Posts: 9
Joined: Sun Jul 03, 2011 1:22 am

Re: playtime_string

Postby James Heinrich » Mon Aug 01, 2011 2:27 pm

Referencing cross-posted wishlist thread.
James Heinrich
getID3() v1 developer
 
Posts: 1203
Joined: Fri May 04, 2001 11:00 am
Location: London, ON, Canada

Re: playtime_string

Postby mrgoe » Tue Jun 19, 2012 7:44 pm

It gets just the headers, and not the actual "body" of the file. From this we can get the filesize without downloading the whole file.
mrgoe
User
 
Posts: 1
Joined: Tue Jun 19, 2012 7:43 pm

Re: playtime_string

Postby tomriddle » Fri Jun 22, 2012 7:36 am

mrgoe wrote:It gets just the headers, and not the actual "body" of the file. From this we can get the filesize without downloading the whole file.


In some cases, but sometimes you need the whole file to be able to perform such operations, right?
I know that's the case with images, but how would it work externally for MP3s or example...
tomriddle
User
 
Posts: 3
Joined: Thu May 31, 2012 11:06 am

Re: playtime_string

Postby James Heinrich » Fri Jun 22, 2012 8:02 am

Most files can be analyzed with only a few kB from the start of the file. Some formats contain all necessary data in the header; some partly between header and filesize; some need to walk the entire file; some tags (ID3v1, APE, Lyrics3, etc) are at the end of the file. So it's variable, depending not only on the file format but also the many possible variations within each format.
James Heinrich
getID3() v1 developer
 
Posts: 1203
Joined: Fri May 04, 2001 11:00 am
Location: London, ON, Canada


Return to Support 1.x (resolved)

Who is online

Users browsing this forum: No registered users and 1 guest

cron