I would like to set meta data to MP4 file.
I create MP4 file via:
new MediaMuxer(mPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
and file has meta:
Title: unknown
Artist: unknown
Album: unknown
Comment:
...
similar as: Here
I found that for API21+ i could make metadata via: MediaMetadata.Builder but how could i save metadata to created MP4 file?
Without extern library please.
Thank you.
To edit/write metadata, Android SDK doesn´t have any method, probably by copyright issues, but you can use options like:
https://github.com/sannies/mp4parser
http://multimedia.cx/eggs/supplying-ffmpeg-with-metadata/
Probably this is what you are looking for (using FFmpeg):
https://github.com/bytedeco/javacv/blob/master/src/main/java/org/bytedeco/javacv/FFmpegFrameRecorder.java
Related
When I try to open a .json file with
startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/json"
}, 0)
the chooser lists files of all types instead of just .json files. And what's worth, all files are greyed out, I can't select any, not even my .json files.
However, when I change application/json to */*, the files aren't greyed out and I can open them.
With ACTION_GET_CONTENT instead of ACTION_OPEN_DOCUMENT the behaviour is the same.
Why doesn't the type setting work as expected? How to make it work?
Android does not support json as a MIME type. You can check out the source codes of MimeUtils.
MimeTypeMap.getSingleton().getMimeTypeFromExtension("json");
returns null;
You can use "application/octet-stream" instead of "application/json"
. It will show "*.json files among other files though it will filters out images, videos, music & text files.
Currently I am downloading a ".mp4" video and saving it in a folder. I want to hide it from gallery. I know how to hide a folder. Currently I am saving it in a different extension for ex. like ".sss" and it is saving properly. Now how can I play that video in my application.
I tried to change the extension and in file and try to play it, but it is not working, here is my code
File extStore = Environment.getExternalStorageDirectory()+"/"+"downloadFolder"+"/"+"video1.sss".replace(".sss",".mp4");
JCVideoPlayer mJcVideoPlayerStandard = (JCVideoPlayerStandard) findViewById(R.id.videoplayer);
mJcVideoPlayerStandard.setUp(extStore.getPath(),JCVideoPlayerStandard.SCREEN_LAYOUT_NORMAL, "Normal");
mJcVideoPlayerStandard.showContextMenu();
I am using this path to play the video,and I am usign JcVideo player lib for playing the video, here is the gradle for it
compile 'fm.jiecao:jiecaovideoplayer:5.4'
When I am saving the file in ".mp4" format I am able to play the video. But when I use different format,I am not able to play it. Any help will be preferable
I think what you are trying to do is to rename the file to mp4 before you play it?
If so the code above is replacing the the '.sss' with '.mp4' in the search string rather than renaming it in the file system.
In other words the line:
File extStore = Environment.getExternalStorageDirectory()+"/"+"downloadFolder"+"/"+"video1.sss".replace(".sss",".mp4");
simply translates to:
File extStore = Environment.getExternalStorageDirectory()+"/"+"downloadFolder"+"/"+"video1.mp4";
As your actual file is still video1.sss you get an error when you try to play a file named video1.mp4 as it can't be found.
If you do want to rename a file you can do it like this:
File file1 = new File("Path of file");
File file2 = new File("Path with new name for the file");
boolean ok = file1.renameTo(file2);
I think you simply can't do it! by changing the extension of a video file you can't play it. because no matter what its extension is, the Audio and Video format coding format won't change by changing extension name. If a player can't play such extension, it is not in its supported video codec.
The Audio and Video format define how a video file is build byte to byte. check this Wikipedia page.
I tried a while to get the pretrained model working on android. The problem is, I only got the ckpt and meta file for the pretrained net. In my opinion I need the .pb for the android app. So I tried to convert the given files to an .pb file.
Therefore I tried the freeze_graph.py but without succes. So I used the example code from https://github.com/openimages/dataset/blob/master/tools/classify.py and modified it to store a pb. file after loading
if not os.path.exists(FLAGS.checkpoint):
tf.logging.fatal(
'Checkpoint %s does not exist. Have you download it? See tools/download_data.sh',
FLAGS.checkpoint)
g = tf.Graph()
with g.as_default():
input_image = tf.placeholder(tf.string)
processed_image = PreprocessImage(input_image)
with slim.arg_scope(inception.inception_v3_arg_scope()):
logits, end_points = inception.inception_v3(
processed_image, num_classes=FLAGS.num_classes, is_training=False)
predictions = end_points['multi_predictions'] = tf.nn.sigmoid(
logits, name='multi_predictions')
init_op = control_flow_ops.group(tf.global_variables_initializer(),
tf.global_variables_initializer(),
data_flow_ops.initialize_all_tables())
saver = tf_saver.Saver()
sess = tf.Session()
saver.restore(sess, FLAGS.checkpoint)
outpt_filename = 'output_graph.pb'
#output_graph_def = sess.graph.as_graph_def()
output_graph_def = graph_util.convert_variables_to_constants(sess, sess.graph.as_graph_def(), ["multi_predictions"])
with gfile.FastGFile(outpt_filename, 'wb') as f:
f.write(output_graph_def.SerializeToString())
Now my problem is that I have the .pb file but I don't have any opinion what is the input node name and I am not sure if multi_predictions is the right output name. In the example android app I have to specify both. And the android app crashed with:
tensorflow_inference_jni.cc:138 Could not create Tensorflow Graph: Invalid argument: No OpKernel was registered to support Op 'DecodeJpeg' with these attrs.
I don't know if there are more problem by trying to fix the .pb problem. Or if anyone knows a better way to port the ckpt and meta files to a .pd file in my case or knows a source for the final file with input and ouput names please give me a hint to complete this task.
Thanks
You'll need to use the optimize_for_inference.py script to strip out the unused nodes in your graph. "decodeJpeg" is not supported on Android -- pixel values should be fed in directly. ClassifierActivity.java has more detail about the specific nodes to use for inception v3.
I'm using mp4parser to mux h264 and aac file which are re-encoded from orginal video file,how can I write the metadata of the original video to the new mp4 file? Or is there a common method to write metadata to mp4 file?
metadata and MP4 is a really problem. There is no generally supported specification. But this is only one part of the problem.
Prob (1): When to write metadata
Prob (2): What to write
Prob (1) is relatively easy to solve: Just extend the DefaultMp4Builder or the FragmentedMp4Builder on your own and override the
protected ParsableBox createUdta(Movie movie) {
return null;
}
with something meaningful. E.g.:
protected ParsableBox createUdta(Movie movie) {
UserDataBox udta = new UserDataBox();
CopyrightBox copyrightBox = new CopyrightBox();
copyrightBox.setCopyright("All Rights Reserved, me, myself and I, 2015");
copyrightBox.setLanguage("eng");
udta.addBox(copyrightBox);
return udta;
}
some people used that to write apple compatible metadata but even though there are some classes in my code I never really figured out what works and what not. You might want to have a look into Apple's specification here
And yes: I'm posting this a year to late.
It seems that the 'mp4parser' library (https://code.google.com/p/mp4parser/), supports writing Metadata to mp4 files in Android. However, I've found there's little-to-no documentation on how to do this, beyond a few examples in their codebase. I've had some luck with the following example, which writes XML metadata into the 'moov/udta/meta' box:
https://github.com/copiousfreetime/mp4parser/blob/master/examples/src/main/java/com/googlecode/mp4parser/stuff/ChangeMetaData.java
If you consider the alternatives you might want to look at JCodec for this purpose. It now has the org.jcodec.movtool.MetadataEditor API (and a matching CLI org.jcodec.movtool.MetadataEditorMain).
Their documentation contains many samples: http://jcodec.org/docs/working_with_mp4_metadata.html
So basically when you want to add some metadata you need to know what key(s) it corresponds to. One way to find out is to inspect a sample file that already has the metadata you need. For this you can run the JCodec's CLI tool that will just print out all the existing metadata fields (keys with values):
./metaedit <file.mp4>
Then when you know the key you want to work with you can either use the same CLI tool:
# Changes the author of the movie
./metaedit -f -si ©ART=New\ value file.mov
or the same thing via the Java API:
MetadataEditor mediaMeta = MetadataEditor.createFrom(new
File("file.mp4"));
Map<Integer, MetaValue> meta = mediaMeta.getItunesMeta();
meta.put(0xa9415254, MetaValue.createString("New value")); // fourcc for '©ART'
mediaMeta.save(false); // fast mode is off
To delete a metadata field from a file:
MetadataEditor mediaMeta = MetadataEditor.createFrom(new
File("file.mp4"));
Map<Integer, MetaValue> meta = mediaMeta.getItunesMeta();
meta.remove(0xa9415254); // removes the '©ART'
mediaMeta.save(false); // fast mode is off
To convert string to integer fourcc you can use something like:
byte[] bytes = "©ART".getBytes("iso8859-1");
int fourcc =
ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN).getInt();
If you want to edit/delete the android metadata you'll need to use a different set of fucntion (because it's stored differently than iTunes metadata):
./metaedit -sk com.android.capture.fps,float=25.0 file.mp4
OR alternatively the same through the API:
MetadataEditor mediaMeta = MetadataEditor.createFrom(new
File("file.mp4"));
Map<String, MetaValue> meta = mediaMeta.getKeyedMeta();
meta.put("com.android.capture.fps", MetaValue.createFloat(25.));
mediaMeta.save(false); // fast mode is off
I have a set of mp4 files that I need to load onto an SD Card and read in my Android app.
The app needs to be able to search the videos by category, so my plan was to add some category info in the mp4 metadata before loading them (probably in the "description" field) and then use a ManagedQuery on the MediaStore.Video.Media.EXTERNAL_CONTENT_URI to find them.
I have updated the "description" field using Adobe Bridge, but when I look at the tags returned by a search, the "description" field is always null. Clearly, the data I'm writing to the mp4 files is not being picked up when Android looks at the video file.
Is there another way I should be writing/searching video metadata?
You should probably look at MediaStore.Video.VideoColumns.DESCRIPTION.
You can query the MediaStore.Video.Media.EXTERNAL_CONTENT_URI as you would any other content provider: http://developer.android.com/guide/topics/providers/content-providers.html#querying
You can add/delete/lookup metadata fields in MP4 files using JCodec's MetadataEditor class.
If you want to add metadata field to MP4 file you can use:
MetadataEditor mediaMeta = MetadataEditor.createFrom(new
File("file.mp4"));
Map<String, MetaValue> meta = mediaMeta.getKeyedMeta();
meta.put("com.android.capture.fps", MetaValue.createFloat(25.));
mediaMeta.save(false); // fast mode is off
Alternatively the same can be done from the command line with the CLI tool (MetadataEditorMain):
./metaedit -sk com.android.capture.fps,float=25.0 file.mp4
In the Java code you can get the list of metadata like so:
MetadataEditor mediaMeta = MetadataEditor.createFrom(new
File("file.mp4"));
Map<String, MetaValue> meta = mediaMeta.getKeyedMeta();
for (String key : meta.keySet()) {
System.out.println(key + ": " + meta.get(key));
}
OR from the command line:
./metaedit <file.mp4>
Read more about it: http://jcodec.org/docs/working_with_mp4_metadata.html