playtime_string

Locked
Lenton
User
Posts: 8
Joined: Fri Jul 08, 2011 2:14 pm
Are you a spambot?: no

playtime_string

Post by Lenton » Sat Jul 09, 2011 4:19 pm

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

James Heinrich
getID3() v1 developer
Posts: 1468
Joined: Fri May 04, 2001 4:00 pm
Are you a spambot?: no
Location: Northern Ontario, Canada
Contact:

Re: playtime_string

Post by James Heinrich » Sat Jul 09, 2011 8: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).

Lenton
User
Posts: 8
Joined: Fri Jul 08, 2011 2:14 pm
Are you a spambot?: no

Re: playtime_string

Post by Lenton » Tue Jul 12, 2011 9: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?

Pernod
getID3() contributor
Posts: 103
Joined: Sat Mar 21, 2009 5:30 pm
Are you a spambot?: no
Location: London, UK
Contact:

Re: playtime_string

Post by Pernod » Tue Jul 12, 2011 10: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.

Windoves
User
Posts: 9
Joined: Sun Jul 03, 2011 6:22 am
Are you a spambot?: no

Re: playtime_string

Post by Windoves » Sun Jul 31, 2011 6: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?

James Heinrich
getID3() v1 developer
Posts: 1468
Joined: Fri May 04, 2001 4:00 pm
Are you a spambot?: no
Location: Northern Ontario, Canada
Contact:

Re: playtime_string

Post by James Heinrich » Sun Jul 31, 2011 11: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.

Windoves
User
Posts: 9
Joined: Sun Jul 03, 2011 6:22 am
Are you a spambot?: no

Re: playtime_string

Post by Windoves » Sun Jul 31, 2011 6: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.

James Heinrich
getID3() v1 developer
Posts: 1468
Joined: Fri May 04, 2001 4:00 pm
Are you a spambot?: no
Location: Northern Ontario, Canada
Contact:

Re: playtime_string

Post by James Heinrich » Sun Jul 31, 2011 8: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.

Windoves
User
Posts: 9
Joined: Sun Jul 03, 2011 6:22 am
Are you a spambot?: no

Re: playtime_string

Post by Windoves » Mon Aug 01, 2011 2:41 am

EDIT: FIXED, see post below
Last edited by Windoves on Mon Aug 01, 2011 6:35 am, edited 2 times in total.

Windoves
User
Posts: 9
Joined: Sun Jul 03, 2011 6:22 am
Are you a spambot?: no

Re: playtime_string

Post by Windoves » Mon Aug 01, 2011 6: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;

?>


Pernod
getID3() contributor
Posts: 103
Joined: Sat Mar 21, 2009 5:30 pm
Are you a spambot?: no
Location: London, UK
Contact:

Re: playtime_string

Post by Pernod » Mon Aug 01, 2011 12:40 pm

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.

Windoves
User
Posts: 9
Joined: Sun Jul 03, 2011 6:22 am
Are you a spambot?: no

Re: playtime_string

Post by Windoves » Mon Aug 01, 2011 5: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.

James Heinrich
getID3() v1 developer
Posts: 1468
Joined: Fri May 04, 2001 4:00 pm
Are you a spambot?: no
Location: Northern Ontario, Canada
Contact:

Re: playtime_string

Post by James Heinrich » Mon Aug 01, 2011 7:27 pm

Referencing cross-posted wishlist thread.

mrgoe
User
Posts: 1
Joined: Wed Jun 20, 2012 12:43 am
Are you a spambot?: no

Re: playtime_string

Post by mrgoe » Wed Jun 20, 2012 12:44 am

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.

tomriddle
User
Posts: 3
Joined: Thu May 31, 2012 4:06 pm
Are you a spambot?: no

Re: playtime_string

Post by tomriddle » Fri Jun 22, 2012 12:36 pm

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...

James Heinrich
getID3() v1 developer
Posts: 1468
Joined: Fri May 04, 2001 4:00 pm
Are you a spambot?: no
Location: Northern Ontario, Canada
Contact:

Re: playtime_string

Post by James Heinrich » Fri Jun 22, 2012 1:02 pm

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.

Locked