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!
Related
What are the standard ways of reading and writing audio files on Android / Kotlin?
I am very confused. I've found plenty of posts that discuss this at some level, but they're all either giving a third party answer (someone's own implementation like https://medium.com/#rizveeredwan/working-with-wav-files-in-android-52e9500297e or https://stackoverflow.com/a/43569709/4959635 or https://gist.github.com/kmark/d8b1b01fb0d2febf5770) or using some Java class, of which I don't know how it's related to the Android SDK (https://stackoverflow.com/a/26598862/4959635, https://gist.github.com/niusounds/3e49013a8e942cdba3fbfe1c336b61fc, https://github.com/google/oboe/issues/548#issuecomment-502758633).
I cannot find a standard way from the Android documentation. Some answer said to use https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-input-stream/read-bytes.html for reading, but I'm quite sure this doesn't parse the file header.
So what's the standard way of processing audio files on Android / Kotlin?
I'm already using dr_wav just fine on desktop, so I am actually thinking of just using that through NDK and maybe creating a wrapper to it.
Your use case is not clear from the question.
Assuming that you need to process raw audio data (PCM samples) - the standard way is to read the (compressed) input file using the MediaExtractor and decode the packets using the MediaCodec. Note that the documentation includes some example code.
The MediaCodec outputs ByteBuffers containing raw PCM samples. The binary format is described here.
Well, there is no strict standard.
In production, you usually choose stable third party library or your company's reusable internal solution for this kind of tasks. You still can implement it yourself, but it will cost you time, since most likely the implementation will consist of hundreds of lines of code and you probably will just create another variation of existing solution which is present on the internet.
I'm writing an Android app that has to perform audio processing (more specifically, MFCC). I have decided to use the TarsosDSP library, but it does not provide a way to pass a sound file to it, as opposed to microphone input. This means that we currently have to write a class that implements a specific interface: basically, it's a wrapper around a buffer of doubles.
Do you know of a way to get the samples as a double from a music file format that Android supports ? We've been scouring the net for a solution but we haven't found one that is generic enough.
Thanks for the help !
I had the same problem for a while and found this:
https://0110.be/posts/Decode_MP3s_and_other_Audio_formats_the_easy_way_on_Android
You can still use the pipe in android. The code in the link allows you pass audio files directly into the decoder. It also contains the ffmpeg binaries required for the assets.
the link takes you through the steps. Good luck.
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.
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.
Requirement
Android open a .wav file in sd card, play it , add some effect (like echo, pitch shift etc), save the file with effect. Simple :(
What I know
I can open and play file using Soundpool or MediaPlayer.
I can give some effect while playing using both. ie for Media Player
I can set Environmental Reverb effect. Using SoundPool I can set
playing rate, which is kind of like pitch shift. I am successful in
implementing these right now.
But either of this classes doesn't have any method to save the
played file. So I can only play, I cannot save the music with
effect.
What I want to know
Is there any other classes of interest, other than MediaPlayer or
SoundPool. Never mind about saving, you just mention the class, I will do the
research about saving file with them.
Any 3rd party libraries where I can add effects and save? Happy if
it is open source and free. But mention them even if it is
proprietary.
Any other areas where I can look into. Does OpenAL support voice
filtering along with voice positioning? Will it work with Android?
Ready to do the dirty work. You please lend me the path..
EDIT: Did some more searching, and come across AudioTrack. But it also won't support saving to a file. So no luck there also..
EDIT Ok, what if I do it myself? Get raw bytes from a wav file, and work on that. I recorded a wav file using AudioRecord, got a wav file. Is there any resource describing low level audio processing (I mean at the bytes level).
EDIT Well bounty time is up, and I am giving bounty to the only answer that I got. After 7 days, what I understood is
We can't save what we play using MediaPlayer, AudioTrack etc.
There is no audio processing libraries available to use.
You can get raw wav files, and do the audio processing yourself. The
answer gave a good wrapper class for reading/writing wav files. A
good java code to read and change pitch of wav files is here.
The WavFile class http://www.labbookpages.co.uk/audio/javaWavFiles.html claims to read and write wav files and allow per-sample manipulation through arrays of sample values. It's certainly reasonably small, 23kbytes total source code.
I did struggle for a while to build an android app with the Wavfile Class included. This turned out to be because both WavFile and ReadExample (from the above link) were intended as standalone java programs, so include a method main(String [] args){}. Eclipse sees this and thinks the Class is a standalone runnable program, and, when I click the run button, tries to execute just the one Class with the java in the development machine, instead of launching the whole app to my phone. When I take care to run the whole app with the little drop-down menu on the run button, I don't have any trouble, and the WavFile Class and examples drop straight in, give zero warnings in the IDE, and work as advertised running on my phone.