How to play a zipped wave file in Flash Mobile - android

I am working on a project in Flash Mobile using ActionScript. I have a zipped wav file that I need to be able to de serialize and play as needed in a Button Press action. Below is the code for zipping the wav file.
mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler);
btnRecord.setStyle("icon", recOff);
sampleCount++;
// save the raw PCM samples as a bare WAV file
var wav:ByteArray = new ByteArray();
var writer:WAVWriter = new WAVWriter();
writer.numOfChannels = 1;
writer.sampleBitRate = 16;
writer.samplingRate = 11025;
samples.position = 0;
writer.processSamples(wav, samples, 11025, 1);
wav.position = 0;
// zip the WAV file
var fzip:FZip = new FZip();
fzip.addFile(name + sampleCount.toString(), wav);
var zip:ByteArray = new ByteArray();
fzip.serialize(zip);
var recSpot:Object = {
id: null,
audio: zip,
name: "New Audio File " + newRecNum,
existsdb: "false"
};
newRecNum++;
recordings.addItem(recSpot);
}
What can I do to play this file, really haven't had to play a zipped file before.

I'm not familiar with WAVWriter (which is probably somewhat beside the point), but here's what I do know.
Firstly, because of the nature of a compression, you cannot (as far as I know) play a zipped audio file, period. You will need to unzip it first.
A quick Google search turned up THIS AS3 TUTORIAL on unzipping with FZIP. The example program is using .PNGs, but I would assume you can adjust it to work with the raw .WAV file you zipped earlier. Skip down to Step 5 for the actual code. (You'll need to rewrite it to work with your interface, obviously.)
You won't need the DataProvider variable in step 5, as that is for components, specifically. You'll need to load your data into something else. If your method of playing WAV files is anything like mine (I use the as3WAVSound class), you'll probably want to load the data into a ByteArray and play off of that.
You also probably won't need the for loop he uses in step 10, as your code appears to be creating a ZIP with only one WAV file. That simplifies things considerably.
Anyway, I hope that answers your question!

Related

Copy two or more (.wav) files into one single file(Appending multiple .wav files in one file in android)

I have got multiple files containing audio in .wav format/extension,
As android is not providing us with AudioInputStream how can i copy without it, below is the list of audioFiles:
List<File> audioFiles = new Arraylist<>();
for(File file : audioFiles) {
try...
catch...
}
I have been scratching my head since long time
Any help would be much Appreciated.
:-)
Actually OutputStream was missing a valid header so i created a helper class for writing a header for the file were all concatenated audio get written to.
and this helped me for Generating header for the (.wav) file

Can we change the extension of video and play it?

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.

How to write metadata to mp4 file using mp4parser?

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

Is it possible to get duration of the remote audio file without downloading it?

I have an Url of the remote audio file. I need to build data for adapter list with track details. Here is this part of code
Log.d("audioURL", audio.getUrl());
MediaPlayer tmpMedia;
tmpMedia = MediaPlayer.create(getContext(), Uri.parse(audio.getUrl()));
holder.txtDuration.setDuration(tmpMedia.getDuration()/1000);
tmpMedia.release();
But it works too slowly. LogCat writes something like this:
15:05:51.783: D/audioURL(776): http://cs4859.vk.me/u14195999/audios/0cbd695ddf50.mp3
15:05:51.783: D/MediaPlayer(776): Couldn't open file on client side, trying server side
15:05:53.813: D/audioURL(776): http://cs4859.vk.me/u14195999/audios/0cbd695ddf50.mp3
15:05:53.823: D/MediaPlayer(776): Couldn't open file on client side, trying server side
15:05:55.373: D/audioURL(776): http://cs4859.vk.me/u14195999/audios/0cbd695ddf50.mp3
15:05:55.383: D/MediaPlayer(776): Couldn't open file on client side, trying server side
15:05:58.143: D/audioURL(776): http://cs1626.vk.me/u149968/audios/04298447cd3c.mp3
15:05:58.153: D/MediaPlayer(776): Couldn't open file on client side, trying server side
...and so on. So, my playlist of about 30 tracks initializes with about 7 minutes.
I guess, the MediaPlayer class method getDuration() sequentially downloads these tracks (or some parts of them) to get their durations.
Is there a way to get these durations quickly, without downloading tracks?
Halim Qarroum, it seems to be a correct way, but I have some troubles with MediaMetadataRetriever class.
Here is my code above:
if (android.os.Build.VERSION.SDK_INT < 10){
holder.txtDuration.setDuration(audio.getTrackDuration());
} else {
MediaMetadataRetriever mRetriever = new MediaMetadataRetriever();
Log.d("URI", Uri.parse(audio.getUrl()).toString());
mRetriever.setDataSource(getContext(), Uri.parse(audio.getUrl()));
String s = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
holder.txtDuration.setDuration(Long.parseLong(s));
mRetriever.release();
}
Application terminates in mRetriever.setDataSource(getContext(), Uri.parse(audio.getUrl())); because of IllegalArgumentException. The audio.getURl() string is http://cs4859.vk.me/u14195999/audios/134dfe90d1ec.mp3.
Why the exception occurs?
Dheeb posted a well detailed answer. However, ID3 tags are not always present in an mp3 file. Instead of looking for these tags, which will force you to limit this method to mp3 files, you could use the MediaMetadataRetriever class which comes with the Android framework.
This class can give you several metadata from certain types of audio/video files, one of this information, is the duration. This method has the advantage to be standard, as it comes with the Android SDK and is not limited to one audio format.
From the Android developers related page :
MediaMetadataRetriever class provides a unified interface for
retrieving frame and meta data from an input media file.
A trivial example of code using this class :
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(your_data_source);
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long timeInmillisec = Long.parseLong( time );
long duration = timeInmillisec / 1000;
long hours = duration / 3600;
long minutes = (duration - hours * 3600) / 60;
long seconds = duration - (hours * 3600 + minutes * 60);
There was bug related to MediaMetadataRetriever.
You could try,
metaRetreiver.setDataSource("<remoteUrl>", new HashMap<String, String>());
I'll assume mp3 since "Audio File" is a blanket phrase.
Method 1: fetch ID3 tag
Variant 1: 3rd party library
You will need to look at the ID3 tags in the mp3 file.
Unless you keep track of the metadata you want somewhere else.
To specifically get the Track length of the file you will need to look into the ID3 metadata tag for sure, specifically the 'TRCK' frame of the tag.
To only download the ID3 Tag part, you must first download the ID3 header part of the file.
This website contains very specific information about the ID3 Tag format. You will need to look at the version number of the ID3 Tag and then, based on that, you will need to find the information regarding how long the ID3 Tag is. Then, you must download the WHOLE tag because the frames are not in any specific order.
Then you should be able to use a third party library to find the TRCK frame and its data.
Variant 2: HTTP Hack
For ID3v2 tags, grab the start of the file. (It's possible for ID3v2 frames to be elsewhere, but in practice they're always there.) You can't tell how long the tag is going to be in advance. For text-only tags you're likely to find the information you want in the first 512-1024 bytes. Unfortunately more and more MP3s have embedded ‘album art’ pictures, which can be much longer; try to pick an ID3 library that will gracefully ignore truncated ID3 information.
ID3v1 tags are located at the end of the file. Again you can't tell how long they're going to be. And of course you don't know in advance whether the file has ID3v1 tags, ID3v2 tags, both or neither. Generally these days ID3v2 is a better bet though.
To read part of a file through HTTP you need the Range header. This too is not supported everywhere.
Method 2: Estimation
File size you can get with an HTTP HEAD request. Duration meaning playing time in seconds, cannot be gotten without fetching the entire file. You can guess, by fetching the first few MP3 frames, looking at their bitrate, and assuming that the rest of the file has the same bitrate, but given the popularity of Variable Bit-Rate encoding the likelihood this will be close to accurate is quite low.
ID3 tags can in theory contain information that might allow you to
guess the length better, in the ASPI and ETCO tags. But in practice
these are very rarely present.
Credits
Credits go to various authors on SO and the interwebs, ofcourse the guy on the first floor in my head.

Is there a way to compare two song(Audio/Video) file?

How to compare two song stored in two files and see, if they are same or not?
Assuming you're not just looking to compare the files, but the actual music encoded within, you need to come up with a way to generate a fingerprint. For music, check out the MusicBrainz.org - they have open source libraries for getting from a song to it's metadata. Not sure if such a project exists for video though.
Use a open source Library for it. like musicg . Only down side is using that library is you can only compare wave files.
Yes this is possible by using the Follow this article
Download the Apache Commons IO 2.5 API from Here
Add jar file in tools which you are following. (netbeans,eclips,android studio)
Import libarary "import org.apache.commons.io.FileUtils";
you then have to use only this function.
File file1 = new File("1st_File_Path");
File file2 = new File("2nd_File_Path");
boolean compareResult = FileUtils.contentEquals(file1, file2);
System.out.println("Are the files are same? " + compareResult);
must remember to vote :)

Categories

Resources