Commit 15c7234d authored by Andreas Kromke's avatar Andreas Kromke
Browse files

get duration of (most) mp4 files in the own Java tag reader library, mp3 and...

get duration of (most) mp4 files in the own Java tag reader library, mp3 and others still missing and report zeros
parent acc84263
......@@ -80,6 +80,11 @@ public abstract class TagsBase
public int coverPictureType = 0; // 0: none or unknown, 1: jpeg, 2: png
public int tagType = 0; // 0: unknown, 1: ID3v1, 2: ID3v2, 10: MP4, 11: Vorbis
// duration
public int timeScale = 1000; // units per second
public int durationUnits = -1; // number of units, -1: unknown
public int durationMs = -1; // derived: duration in [ms], -1: unknown
// configuration
public static final boolean doTrim = true; // remove leading and trailing spaces
public static final boolean doEmptyAsNull = true; // set empty strings as null pointer
......@@ -384,6 +389,8 @@ public abstract class TagsBase
* "n movement" or
* "n/m movement"
*
* also calculate duration in [ms]
*
***********************************************************************************/
@SuppressWarnings("WeakerAccess")
public void combineValues()
......@@ -431,6 +438,17 @@ public abstract class TagsBase
}
values[idCombinedMovement] = result;
// duration
if ((durationUnits > 0) && (timeScale > 0))
{
// convert to ms (needs 64 bit arithmetic)
long temp = durationUnits;
temp *= 1000;
temp /= timeScale;
durationMs = (int) temp; // reduce to 32 bits
}
}
......@@ -686,6 +704,18 @@ public abstract class TagsBase
{
Log.d(LOG_TAG, "dump() -- tag type = " + tagType);
}
if (durationMs > 0)
{
int duration_s = durationMs / 1000; // seconds
int duration_min = duration_s / 60;
duration_s -= 60 * duration_min;
Log.d(LOG_TAG, "dump() -- duration is " + durationMs + " ms (" + duration_min + ":" + duration_s + ")");
}
else
{
Log.d(LOG_TAG, "dump() -- (duration is unknown)");
}
}
......
......@@ -197,7 +197,7 @@ public class TagsMp4 extends TagsBase
return safeSkip(boxPayloadSize);
}
// some boxes, called "full boxes", have version and flags
// some boxes, called "full boxes", have version and flags (four bytes)
boolean readVersionAndFlags()
{
byte[] v = new byte[4];
......@@ -209,8 +209,24 @@ public class TagsMp4 extends TagsBase
boxPayloadSize = boxSize - bytesRead;
version = v[0] & 0xff;
flags = getBigEndianInt3(v, 1);
Log.d(LOG_TAG, "Mp4Box::check() : " + levelStr + " version = " + version + ", flags = " + flags);
Log.d(LOG_TAG, "Mp4Box::check() : " + levelStr + " remaining payload size = " + boxPayloadSize);
Log.d(LOG_TAG, "Mp4Box::readVersionAndFlags() : " + levelStr + " version = " + version + ", flags = " + flags);
Log.d(LOG_TAG, "Mp4Box::readVersionAndFlags() : " + levelStr + " remaining payload size = " + boxPayloadSize);
return true;
}
boolean readMovieHeader()
{
byte[] v = new byte[96];
bytesRead += v.length;
if (!readBytes(v))
{
return false;
}
boxPayloadSize = boxSize - bytesRead;
timeScale = getBigEndianInt4(v, 8);
durationUnits = getBigEndianInt4(v, 12);
Log.d(LOG_TAG, "Mp4Box::readMovieHeader() : " + levelStr + " timescale = " + timeScale + ", duration = " + durationUnits);
Log.d(LOG_TAG, "Mp4Box::readMovieHeader() : " + levelStr + " remaining payload size = " + boxPayloadSize);
return true;
}
......@@ -451,12 +467,33 @@ public class TagsMp4 extends TagsBase
}
}
else
if (box.boxType.equals("mvhd"))
{
// header
if (!box.readVersionAndFlags())
{
return false;
}
if (!box.readMovieHeader())
{
return false;
}
// skip remaining payload, if any
if (!box.skipPayload())
{
res = false;
break;
}
}
else
if (box.boxType.equals("meta"))
{
// header
if (!box.readVersionAndFlags())
{
return false;
}
// recursion
if (!read_container(box))
{
return false;
......
......@@ -72,6 +72,17 @@ public class MyTaggerInterface extends TaggerInterface
// replace numerical genres with text
tags.replaceNumericalGenres();
// calculate duration, if possible
int duration;
if (tags.durationMs > 0)
{
duration = tags.durationMs;
}
else
{
duration = 0;
Log.w(LOG_TAG, "readTagsFromUri() : unknown duration");
}
MusicDatabase.AudioFile af = new MusicDatabase.AudioFile();
af.id = -1; // add later
af.track_no = 1000 * tags.getNumericValue(TagsBase.idDiscNo, 0) + tags.getNumericValue(TagsBase.idTrackNo, 0);
......@@ -79,7 +90,7 @@ public class MyTaggerInterface extends TaggerInterface
af.title = tags.values[TagsBase.idCombinedMovement]; // automatically falls back to title, if necessary
af.album = tags.values[TagsBase.idAlbum];
af.album_id = -1; // add later
af.duration = 0; // add later
af.duration = duration;
af.grouping = tags.values[TagsBase.idGrouping];
af.subtitle = tags.values[TagsBase.idSubtitle];
af.composer = tags.values[TagsBase.idComposer];
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment