improved video fetch

This commit is contained in:
Thibault Deckers 2020-04-07 22:27:38 +09:00
parent a2fc8bfd2f
commit 3328916c86
3 changed files with 32 additions and 6 deletions

View file

@ -17,6 +17,7 @@ import com.drew.metadata.MetadataException;
import com.drew.metadata.avi.AviDirectory;
import com.drew.metadata.exif.ExifIFD0Directory;
import com.drew.metadata.jpeg.JpegDirectory;
import com.drew.metadata.mp4.Mp4Directory;
import com.drew.metadata.mp4.media.Mp4VideoDirectory;
import java.io.File;
@ -96,11 +97,15 @@ public class ImageEntry {
return width != null && width > 0 && height != null && height > 0;
}
private boolean hasDuration() {
return durationMillis != null && durationMillis > 0;
}
public String getFilename() {
return path == null ? null : new File(path).getName();
}
public boolean isImage() {
private boolean isImage() {
return mimeType.startsWith(MimeTypes.IMAGE);
}
@ -123,7 +128,7 @@ public class ImageEntry {
// finds: width, height, orientation/rotation, date, title, duration
public ImageEntry fillPreCatalogMetadata(Context context) {
fillByMediaMetadataRetriever(context);
if (hasSize()) return this;
if (hasSize() && (!isVideo() || hasDuration())) return this;
fillByMetadataExtractor(context);
if (hasSize()) return this;
fillByBitmapDecode(context);
@ -218,6 +223,12 @@ public class ImageEntry {
height = mp4VideoDir.getInt(Mp4VideoDirectory.TAG_HEIGHT);
}
}
Mp4Directory mp4Dir = metadata.getFirstDirectoryOfType(Mp4Directory.class);
if (mp4Dir != null) {
if (mp4Dir.containsTag(Mp4Directory.TAG_DURATION)) {
durationMillis = mp4Dir.getLong(Mp4Directory.TAG_DURATION);
}
}
} else if (MimeTypes.AVI.equals(mimeType)) {
AviDirectory aviDir = metadata.getFirstDirectoryOfType(AviDirectory.class);
if (aviDir != null) {
@ -227,6 +238,9 @@ public class ImageEntry {
if (aviDir.containsTag(AviDirectory.TAG_HEIGHT)) {
height = aviDir.getInt(AviDirectory.TAG_HEIGHT);
}
if (aviDir.containsTag(AviDirectory.TAG_DURATION)) {
durationMillis = aviDir.getLong(AviDirectory.TAG_DURATION);
}
}
}
} catch (IOException | ImageProcessingException | MetadataException e) {

View file

@ -86,6 +86,8 @@ public class MediaStoreImageProvider extends ImageProvider {
String orderBy = MediaStore.MediaColumns.DATE_TAKEN + " DESC";
int entryCount = 0;
final boolean needDuration = projection == VIDEO_PROJECTION;
try {
Cursor cursor = context.getContentResolver().query(contentUri, projection, null, null, orderBy);
if (cursor != null) {
@ -115,6 +117,7 @@ public class MediaStoreImageProvider extends ImageProvider {
final String mimeType = cursor.getString(mimeTypeColumn);
int width = cursor.getInt(widthColumn);
int height = cursor.getInt(heightColumn);
long durationMillis = durationColumn != -1 ? cursor.getLong(durationColumn) : 0;
Map<String, Object> entryMap = new HashMap<String, Object>() {{
put("uri", itemUri.toString());
@ -126,14 +129,14 @@ public class MediaStoreImageProvider extends ImageProvider {
put("dateModifiedSecs", cursor.getLong(dateModifiedColumn));
put("sourceDateTakenMillis", cursor.getLong(dateTakenColumn));
put("bucketDisplayName", cursor.getString(bucketDisplayNameColumn));
put("durationMillis", durationColumn != -1 ? cursor.getLong(durationColumn) : 0);
// only for map export
put("contentId", contentId);
}};
entryMap.put("width", width);
entryMap.put("height", height);
entryMap.put("durationMillis", durationMillis);
if ((width <= 0 || height <= 0) && !MimeTypes.SVG.equals(mimeType)) {
if (((width <= 0 || height <= 0) && needSize(mimeType)) || (durationMillis == 0 && needDuration)) {
// some images are incorrectly registered in the Media Store,
// they are valid but miss some attributes, such as width, height, orientation
ImageEntry entry = new ImageEntry(entryMap).fillPreCatalogMetadata(context);
@ -142,7 +145,7 @@ public class MediaStoreImageProvider extends ImageProvider {
height = entry.height != null ? entry.height : 0;
}
if ((width <= 0 || height <= 0) && !MimeTypes.SVG.equals(mimeType)) {
if ((width <= 0 || height <= 0) && needSize(mimeType)) {
// this is probably not a real image, like "/storage/emulated/0", so we skip it
Log.w(LOG_TAG, "failed to get size for uri=" + itemUri + ", path=" + path + ", mimeType=" + mimeType);
} else {
@ -158,6 +161,10 @@ public class MediaStoreImageProvider extends ImageProvider {
return entryCount;
}
private boolean needSize(String mimeType) {
return !MimeTypes.SVG.equals(mimeType);
}
@Override
public void delete(final Activity activity, final String path, final Uri uri, final ImageOpCallback callback) {
// check write access permission to SD card

View file

@ -155,7 +155,12 @@ class ImageEntry {
return d == null ? null : DateTime(d.year, d.month, d.day);
}
String get durationText => formatDuration(Duration(milliseconds: durationMillis));
String _durationText;
String get durationText {
_durationText ??= formatDuration(Duration(milliseconds: durationMillis));
return _durationText;
}
bool get hasGps => isCatalogued && _catalogMetadata.latitude != null;