video: metadata fallback
This commit is contained in:
parent
a7f9163ec3
commit
67a5bd3f16
4 changed files with 81 additions and 4 deletions
|
@ -23,7 +23,7 @@ public class MainActivity extends FlutterActivity {
|
|||
FlutterView messenger = getFlutterView();
|
||||
new MethodChannel(messenger, AppAdapterHandler.CHANNEL).setMethodCallHandler(new AppAdapterHandler(this));
|
||||
new MethodChannel(messenger, ImageDecodeHandler.CHANNEL).setMethodCallHandler(new ImageDecodeHandler(this, mediaStoreStreamHandler));
|
||||
new MethodChannel(messenger, MetadataHandler.CHANNEL).setMethodCallHandler(new MetadataHandler());
|
||||
new MethodChannel(messenger, MetadataHandler.CHANNEL).setMethodCallHandler(new MetadataHandler(this));
|
||||
new EventChannel(messenger, MediaStoreStreamHandler.CHANNEL).setStreamHandler(mediaStoreStreamHandler);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package deckers.thibault.aves.channelhandlers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.MediaMetadataRetriever;
|
||||
import android.text.format.Formatter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.adobe.xmp.XMPException;
|
||||
|
@ -7,6 +11,7 @@ import com.adobe.xmp.XMPIterator;
|
|||
import com.adobe.xmp.XMPMeta;
|
||||
import com.adobe.xmp.properties.XMPPropertyInfo;
|
||||
import com.drew.imaging.ImageMetadataReader;
|
||||
import com.drew.imaging.ImageProcessingException;
|
||||
import com.drew.metadata.Directory;
|
||||
import com.drew.metadata.Metadata;
|
||||
import com.drew.metadata.Tag;
|
||||
|
@ -19,12 +24,19 @@ import java.io.InputStream;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import deckers.thibault.aves.utils.Constants;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
||||
public static final String CHANNEL = "deckers.thibault/aves/metadata";
|
||||
|
||||
private Context context;
|
||||
|
||||
public MetadataHandler(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
||||
switch (call.method) {
|
||||
|
@ -61,6 +73,8 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
|||
}
|
||||
}
|
||||
result.success(metadataMap);
|
||||
} catch (ImageProcessingException e) {
|
||||
result.error("getOverlayMetadata-imageprocessing", "failed to get metadata for path=" + path + " (" + e.getMessage() + ")", null);
|
||||
} catch (FileNotFoundException e) {
|
||||
result.error("getOverlayMetadata-filenotfound", "failed to get metadata for path=" + path + " (" + e.getMessage() + ")", null);
|
||||
} catch (Exception e) {
|
||||
|
@ -103,10 +117,46 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
|||
}
|
||||
}
|
||||
result.success(metadataMap);
|
||||
} catch (ImageProcessingException e) {
|
||||
getAllVideoMetadataFallback(call, result);
|
||||
} catch (FileNotFoundException e) {
|
||||
result.error("getAllMetadata-filenotfound", "failed to get metadata for path=" + path + " (" + e.getMessage() + ")", null);
|
||||
} catch (Exception e) {
|
||||
result.error("getAllMetadata-exception", "failed to get metadata for path=" + path, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void getAllVideoMetadataFallback(MethodCall call, MethodChannel.Result result) {
|
||||
String path = call.argument("path");
|
||||
|
||||
try {
|
||||
Map<String, Map<String, String>> metadataMap = new HashMap<>();
|
||||
Map<String, String> dirMap = new HashMap<>();
|
||||
// unnamed fallback directory
|
||||
metadataMap.put("", dirMap);
|
||||
|
||||
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
|
||||
retriever.setDataSource(path);
|
||||
for (Map.Entry<Integer, String> kv : Constants.MEDIA_METADATA_KEYS.entrySet()) {
|
||||
Integer key = kv.getKey();
|
||||
String value = retriever.extractMetadata(key);
|
||||
if (value != null) {
|
||||
switch (key) {
|
||||
case MediaMetadataRetriever.METADATA_KEY_BITRATE:
|
||||
value = Formatter.formatFileSize(context, Long.parseLong(value)) + "/sec";
|
||||
break;
|
||||
case MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION:
|
||||
value += "°";
|
||||
break;
|
||||
}
|
||||
dirMap.put(kv.getValue(), value);
|
||||
}
|
||||
}
|
||||
retriever.release();
|
||||
|
||||
result.success(metadataMap);
|
||||
} catch (Exception e) {
|
||||
result.error("getAllVideoMetadataFallback-exception", "failed to get metadata for path=" + path, e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,37 @@
|
|||
package deckers.thibault.aves.utils;
|
||||
|
||||
import android.media.MediaMetadataRetriever;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Constants {
|
||||
// mime types
|
||||
|
||||
public static final String MIME_VIDEO = "video";
|
||||
public static final String MIME_JPEG = "image/jpeg";
|
||||
public static final String MIME_PNG = "image/png";
|
||||
public static final String MIME_GIF = "image/gif";
|
||||
|
||||
// video metadata keys, from android.media.MediaMetadataRetriever
|
||||
|
||||
public static final Map<Integer, String> MEDIA_METADATA_KEYS = new HashMap<Integer, String>() {
|
||||
{
|
||||
put(MediaMetadataRetriever.METADATA_KEY_MIMETYPE, "MIME Type");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS, "Number of Tracks");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_HAS_AUDIO, "Has Audio");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "Has Video");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_BITRATE, "Bitrate");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION, "Video Rotation");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_DATE, "Date");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_LOCATION, "Location");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_YEAR, "Year");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_ARTIST, "Artist");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST, "Album Artist");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_ALBUM, "Album");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_TITLE, "Title");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_AUTHOR, "Author");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_COMPOSER, "Composer");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_WRITER, "Writer");
|
||||
put(MediaMetadataRetriever.METADATA_KEY_GENRE, "Genre");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ class InfoPageState extends State<InfoPage> {
|
|||
final directory = metadataMap[directoryName];
|
||||
final tagKeys = directory.keys.toList()..sort();
|
||||
return [
|
||||
Padding(
|
||||
if (directoryName.isNotEmpty) Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Text(directoryName, style: TextStyle(fontSize: 18)),
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue