Is there any way to write the 'software' metadata field in mp4's in Android? In the APIs, I see the MediaMetadata class (https://developer.android.com/reference/android/media/MediaMetadata.html), but it seems this is mainly focused on metadata for music (artist, album, etc...).
In short, I'm looking for the equivalent of AVMetadataCommonKeySoftware over in iOS: https://developer.apple.com/library/prerelease/ios/documentation/AVFoundation/Reference/AVFoundationMetadataKeyReference/index.html#//apple_ref/doc/constant_group/Common_Metadata_Keys
No. If I understand you right, are you looking to add/modify a metadata tag? Android itself doesn't support modifying mp4 files. MP4 has a standard place to put metadata, but no standard for what tags to use. It only has a copywrite tag. The mp4 file structure has atoms/boxes and it uses the UTDA sub-box of various other boxes like MOOV for custom data. Some mp4s are written with the ID32 box that contains id3.2 tags. So not all mp4s will be guaranteed to have a software tag or even the same metadata. Apple works with quicktime metadata ('MOOV' box). You can use a java library like mp4parser ( see this answer ) to get the box information, use another library for parsing the tag info for (moov, ID32, ect) and then you would put it back together with your software tag and write it back to the file using mp4parser.
JCodec now provides the API and a CLI tool to add/edit/delete iTunes metadata in MP4 files. Read more about it: http://jcodec.org/docs/working_with_mp4_metadata.html
The CLI is in org.jcodec.movtool.MetadataEditorMain and the API is in org.jcodec.movtool.MetadataEditor.
Here's a usage sample:
# 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 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();
However if you take a freshly transcoded file and re-add metadata to it the iTunes and QuickTime won't see it (though it will show up in mediainfo). It's a known bug and JCodec team is working on it.
Related
I'm using the cordova-plugin-media plugin to record audio-files from android and ios devices.
However, android only allows to record the file in ".amr" ending, iOS on the otherside only supports ".wav".
Playing the ".wav" from the iOS device on Android works, however, iOS doesn't support ".amr" files. That's why I have to convert them somehow.
Since I couldn't find any cordova-plugin converting the ".amr" file on the clientside besides this one (which is based on an external API and extreeeemly slow + not fully working - in addition that I'm not a fan of doing file-conversions on the client-side), I'm looking for a solution on the server-side:
Is there any javascript-library (best if it's "nodejs-friendly") allowing me to easily convert an ".amr" file to a ".wav" or ".mp3" (or similiar - just playable on iOS)?
Despite ffmpeg (which I couldn't manage to install properly), I couldn't find ANY solutions... :(
(setting the mime-type to 'audio/wav' in the cordova-plugin-media creates a "corrupt" wav file, still amr-encode when analyzing it further with a tool...)
I really appreciate your help!
I came up with a "solution", which I share with you if someone else is running in the same problems as I did:
www.cloudconvert.com offers a very simple api for "on-the-fly" converting video/audio/img files.
For node.js there is a node package for that I can recommend: https://github.com/cloudconvert/cloudconvert-node
I decided to convert the .amr to .mp3 and not .wav (iOS "standard") since .mp3 is smaller. To be able to play it on an iOS device though one has to adjust the bitrate a little bit from the (manual) example described on github.
Make sure to pass the following options to your converting process:
ccprocess.start({
outputformat: 'mp3',
input: 'download',
file: 'path-to-your-file',
converteroptions: {
audio_bitrate: "721",
audio_frequency: "44100",
audio_qscale: -1
}
}, function (err, ccprocess) { ...
Android SDK provides class MediaMetadataRetriever for extracting metadata from MP4 files. Is there a way to edit MP4 metadata fields using MediaCodec API (without ffmpeg)? My task is to reset rotation field.
mp4parser seems to be what you are looking for, although I'm not certain where exactly the rotation field is located in the MP4 (I don't know enough about the file layout). If you know which box (or "atom") the metadata is stored in, then the MetaDataRead and MetaDataInsert classes are pretty clear examples of how to read and write the data (they specifically work on the iTunes "Name"/"Title" field, but writing other metadata works the same way, once you know where it should be located). Hope this helps!
I am trying to build an video recording system on Android 4.2.2, I've done the encoding part, which is using OMX. Now I am working on the Muxer part, since the code stream of the video can be a little different if I use FFMpeg, so I wish to use the exact same Muxer tool of the original system.
So I want to extract the Muxer part of StagefrightRecorder, compile it into a .so file, and then call it via JNI in my application. But there are a lot of stuffs in StagefrightRecorder, I am confused.
Can this way work? Can I just extract the code relevant to MPEG4Writer? Can anyone give me any instructions?
Thanks!
If you are compiling within the context of the framework, you could simply include the relevant header files and create the MPEG4Writer object directly. A very good example for this is the command line utility recordVideo as can be observed from this file.
If you wish to write a separate application, then you need to link with libstagefright.so and include the relevant header files and their path.
Note: If you wish to work with the standard MPEG4Writer, it's source i.e. source of the MPEG4Writer which would be an encoder should be modeled as a MediaSource. The writer pulls the metadata and actual bitstream through the read method and hence, it is recommended to employ a standard built-in object such as OMXCodec or ACodec for the encoder.
I can read meta information like title, artist, album art and other information from audio files, but I have never been able to successfully write the meta information.
Any have any experiences with this? Are there better libraries than JAudioTagger?
I'd offer some example code, but I've tried a dozen things that didn't work.
Something like
AudioFile audioFile = AudioFileIO.read(testFile);
Tag newTag = audioFile.getTag();
newTag.setField(FieldKey.ALBUM,"October");
newTag.setField(FieldKey.ARTIST,"U2");
audioFile.commit();
but if you are using android you also need to do
TagOptionSingleton.getInstance().setAndroid(true);
because of some bugs with android version of Java
I am working on an Android application which is supposed to play videos over HTTP on Android devices. Before we setup a server to host the video files just wanted a few things clarified:
As per the developer documentation, Android supports .mp4 and .3gp container formats for video. If we use H.263(video) - AAC LC (Audio) audio-video codec used for our media files will we be able to play the video by passing the URL to MediaPlayer class?
I did a little experiment and passed URL of one of the video files(.mp4) to the MediaPlayer class and got the following error:
Command PLAYER_INIT completed with an
error or info
PVMFErrContentInvalidForProgressivePlayback
From the docs, I came to know that for progressive playback, the video's index (e.g moov atom) should be at the start of the file.
Questions:
1. How do we make our videos Android-ready?
2. What are the different considerations that we need to make?
Please help.
Thanks.
You can actually achieve this using a pure Java implementation of ISO BMF ( MP4 ) container used JCodec ( http://jcodec.org ). For this use the following code:
MovieBox movie = MP4Util.createRefMovie(new File("bad.mp4"));
new Flattern().flattern(movie, new File("good.mp4"));
The side effect of 'Flattern' is creating a web optimized movie file that has it's header BEFORE the data.
You can also use similar functionality from command line:
java -cp jcodec-0.1.3-uberjar.jar org.jcodec.movtool.WebOptimize <movie>
The JCodec library can be downloaded from a project website.
I cross posted this question on Android-developers google group. Mark answered it there. Thanks Mark!
See this thread