merging recorded audio with existing mp3 file android - android

I am learning android development, and trying to make face filters with sound in background like snapchat or Facebook. But I am unable to record the audio playing in the filter with user sound while using headphones.
Please help! or some links which can be useful for me

import java.io.*;
public class TwoFiles
{
public static void main(String args[]) throws IOException
{
FileInputStream fistream1 = new FileInputStream("C:\\Temp\\1.mp3"); // first source file
FileInputStream fistream2 = new FileInputStream("C:\\Temp\\2.mp3");//second source file
SequenceInputStream sistream = new SequenceInputStream(fistream1, fistream2);
FileOutputStream fostream = new FileOutputStream("C:\\Temp\\final.mp3");//destinationfile
int temp;
while( ( temp = sistream.read() ) != -1)
{
// System.out.print( (char) temp ); // to print at DOS prompt
fostream.write(temp); // to write to file
}
fostream.close();
sistream.close();
fistream1.close();
fistream2.close();
}
}

Related

Create Zip File in Xamarin Forms Android

I want to create a zip file in Xamarin Forms Cross Platform.
I use a custom way for every platform, iOS and Android.
In iOS works with the Library ZipArchive, but I not found alternative for Android.
So I try do it native (to create zip with only one file), but the zip file was created empty.
public void Compress(string path, string filename, string zipname)
{
var personalpath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string folder = Path.Combine(personalpath, path);
string zippath = Path.Combine(folder, zipname);
string filepath = Path.Combine(folder, filename);
System.IO.FileStream fos = new System.IO.FileStream(zippath, FileMode.OpenOrCreate);
Java.Util.Zip.ZipOutputStream zos = new Java.Util.Zip.ZipOutputStream(fos);
ZipEntry entry = new ZipEntry(filename.Substring(filename.LastIndexOf("/") + 1));
byte[] fileContents = File.ReadAllBytes(filepath);
zos.Write(fileContents);
zos.CloseEntry();
}
Solution by Leo Nix and OP.
Need to close ZOS.
fos and zos should be disposed.
...
zos.CloseEntry();
zos.Close();
zos.Dispose();
fos.Dispose();
}
I've noticed the ask and solution code wasn't complete. I had to change somethings to make it work, so here is the complete code:
public void ZipFile(string fullZipFileName, params string[] fullFileName)
{
using (FileStream fs = new FileStream(fullZipFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using (ZipOutputStream zs = new ZipOutputStream(fs))
{
foreach (var file in fullFileName)
{
string fileName = Path.GetFileName(file);
ZipEntry zipEntry = new ZipEntry(fileName);
zs.PutNextEntry(zipEntry);
byte[] fileContent = System.IO.File.ReadAllBytes(file);
zs.Write(fileContent);
zs.CloseEntry();
}
zs.Close();
}
fs.Close();
}
}
I hope it help.

Android: video saved to gallery won't play

I've got a rather odd problem. I'm writing an Android application using the Xamarin framework, and I also have an iOS version of the same app also written in Xamarin. In the app the user can send photos and videos to their friends, and their friends may be on either iOS or Android. This all works fine, and videos taken on an iPhone can be played on an Android device and vice versa.
The problem I am having is when I try to programmatically save a video to the Android gallery, then that video is not able to be played in the gallery. It does appear that the video data it's self is actually copied, but the video is somehow not playable.
My videos are encoded to the mp4 format using the H.264 codec. I believe this is fully supported in Android, and like I said the videos play just fine when played via a VideoView in the app.
The code I am using to copy the videos to the gallery is below. Does anyone have any idea what I am doing wrong here?
public static void SaveVideoToGallery(Activity activity, String filePath) {
// get filename from path
int idx = filePath.LastIndexOf("/") + 1;
String name = filePath.Substring(idx, filePath.Length - idx);
// set in/out files
File inFile = new File(filePath);
File outDir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryMovies);
File outFile = new File(outDir, name);
// Make sure the Pictures directory exists.
outDir.Mkdirs();
// save the file to disc
InputStream iStream = new FileInputStream(inFile);
OutputStream oStream = new FileOutputStream(outFile);
byte[]data = new byte[iStream.Available()];
iStream.Read();
oStream.Write(data);
iStream.Close();
oStream.Close();
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.ScanFile(
activity.ApplicationContext,
new String[] { outFile.ToString() },
null,
null);
}
NOTE: I know this is all in C#, but keep in mind that all the Xamarin framework does is provide an API to the native Android methods. Everything I am using is either Java or Android backed classes/functions.
Thanks!
Your issue is in this code snippet:
byte[]data = new byte[iStream.Available()];
iStream.Read();
oStream.Write(data);
There are a few issues here:
You never read the files contents into the data buffer; iStream.Read() will only read a single byte and return it as an integer.
new byte[iStream.Available()] will only allocate the amount of data bytes that are available to be read without blocking. It isn't the full file. See the docs on the available method.
oStream.Write(data) writes out a garbage block of data as nothing is ever read into it.
The end result is the outputted video file is just a block of empty data hence why the gallery cannot use it.
Fix it reading in the data from the file stream and then writing them into the output file:
int bytes = 0;
byte[] data = new byte[1024];
while ((bytes = iStream.Read(data)) != -1)
{
oStream.Write (data, 0, bytes);
}
Full sample:
public static void SaveVideoToGallery(Activity activity, String filePath) {
// get filename from path
int idx = filePath.LastIndexOf("/") + 1;
String name = filePath.Substring(idx, filePath.Length - idx);
// set in/out files
File inFile = new File(filePath);
File outDir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryMovies);
File outFile = new File(outDir, name);
// Make sure the Pictures directory exists.
outDir.Mkdirs();
// save the file to disc
InputStream iStream = new FileInputStream(inFile);
OutputStream oStream = new FileOutputStream(outFile);
int bytes = 0;
byte[] data = new byte[1024];
while ((bytes = iStream.Read(data)) != -1)
{
oStream.Write (data, 0, bytes);
}
iStream.Close();
oStream.Close();
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.ScanFile(
activity.ApplicationContext,
new String[] { outFile.ToString() },
null,
null);
}

Merge two mp3 file in android

I want merge multiple mp3 file in android but for example I just do this with two file :
FileInputStream fileInputStream = new FileInputStream(soundFile.getAbsolutePath() + 0);
FileInputStream fileInputStream1 = new FileInputStream(soundFile.getAbsolutePath() + 1);
SequenceInputStream sequenceInputStream = new SequenceInputStream(fileInputStream, fileInputStream1);
FileOutputStream fileOutputStream = new FileOutputStream(soundFile.getAbsolutePath());
int temp;
while ((temp = sequenceInputStream.read()) != -1) {
fileOutputStream.write(temp);
}
fileInputStream.close();
fileInputStream1.close();
sequenceInputStream.close();
fileOutputStream.close();
I recorded two sound with "ttt.mp30" and "ttt.mp31" file. then I want to merge it to "ttt.mp3"
but when I use this code for merge, it just create the ttt.mp3 witch play ttt.mp30 but it doesn't play ttt.mp31 file
whats the problem ?
thanks
EDIT :
if I use :
SequenceInputStream sequenceInputStream = new SequenceInputStream(fileInputStream1, fileInputStream);
insted of :
SequenceInputStream sequenceInputStream = new SequenceInputStream(fileInputStream, fileInputStream1);
the ttt.mp3 just play ttt.mp31 file
Edit :
the record option :
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
import java.io.*;
public class TwoFiles
{
public static void main(String args[]) throws IOException
{
FileInputStream fistream1 = new FileInputStream("path\\1.mp3"); // first source file
FileInputStream fistream2 = new FileInputStream("path\\2.mp3");//second source file
SequenceInputStream sistream = new SequenceInputStream(fistream1, fistream2);
FileOutputStream fostream = new FileOutputStream("path\\final.mp3");//destinationfile
int temp;
while( ( temp = sistream.read() ) != -1)
{
// System.out.print( (char) temp ); // to print at DOS prompt
fostream.write(temp); // to write to file
}
fostream.close();
sistream.close();
fistream1.close();
fistream2.close();
}
}

Saving ByteArray of audio into an Audio File

I'm working on a test app to integrate soundtouch (an open source audio processing library) on Android.
My test app already can receive input from the mic, pass the audio thru soundtouch and output the processed audio to an AudioTrack instance.
My question is, how can I change the output from AudioTrack to a new File on my device?
Here's the relevant code in my app (where I'm processing the output of soundtouch, into the input for AudioTrack)
// the following code is a stripped down version of my code
// in no way its supposed to compile or work. Its here for reference purposes
// pre-conditions
// parameters - input : byte[]
soundTouchJNIInstance.putButes(input);
int bytesReceived = soundTouchJNIInstance.getBytes(input);
audioTrackInstance.write(input, 0, bytesReceived);
Any ideas on how to approach this problem? Thanks!
Hope you are already getting the input voice from microphone and saved on a file.
Firstly, import JNI libraries to your oncreate method :
System.loadLibrary("soundtouch");
System.loadLibrary("soundstretch");
Soundstrech library :
public class AndroidJNI extends SoundStretch{
public final static SoundStretch soundStretch = new SoundStretch();
}
Now you need to call soundstrech.process with the input file path and the desired output file to store processed voice as parameters :
AndroidJNI.soundStretch.process(dataPath + "inputFile.wav", dataPath + "outputFile.wav", tempo, pitch, rate);
File sound = new File(dataPath + "outputFile.wav");
File sound2 = new File(dataPath + "inputFile.wav");
Uri soundUri = Uri.fromFile(sound);
The soundUri can be provided as a source to media player for play back :
MediaPlayer mediaPlayer = MediaPlayer.create(this, soundUri);
mediaPlayer.start();
Also note that, the sample size for recording should be selected dynamically by declaring an Array of Sample Rates :
int[] sampleRates = { 44100, 22050, 11025, 8000 }
The best way to write byteArray this :
public void writeToFile(byte[] array)
{
try
{
String path = "Your path.mp3";
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream stream = new FileOutputStream(path);
stream.write(array);
} catch (FileNotFoundException e1)
{
e1.printStackTrace();
}
}
I am not aware of sound touch at all and the link i am providing no where deals with jni code, but you can have a look at it if it helps you any way: http://i-liger.com/article/android-wav-audio-recording
I think the best way to achieve this is converting that audio to a byte[] array. Assuming you have already done that (if not, comment it and I'll provide an example), the above code should work. This assumes you're saving it in a external sdcard in a new directory called AudioRecording and saving it as audiofile.mp3.
final File soundFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "AudioRecording/");
soundFile.mkdirs();
final File outFile = new File(soundFile, 'audiofile.mp3');
try {
final FileOutputStream output = new FileOutputStream(outFile);
output.write(yourByteArrayWithYourAudioFileConverted);
output.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mkdirs() method will try to construct all the parent directories if they're missing. So if you're planning to store in a 2 or more level depth directory, this will create all the structure.
I use a simple test code snippet to write my audio byte arrays:
public void saveAudio(byte[] array, string pathAndName)
{
FileOutputStream stream = new FileOutputStream(pathAndName);
try {
stream.write(array);
} finally {
stream.close();
}
}
You will probably need to add some exception handling if you are going to be using this in a production environment, but I utilise the above to save audio whenever I am am in the development phase or for personal non-release projects.
Addendum
After some brief thought I have changed my snippet to the following slightly more robust format:
public void saveAudio(byte[] array, string pathAndName)
{
try (FileOutputStream stream= new FileOutputStream(pathAndName)) {
stream.write(array);
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
stream.close();
}
}
You can use the method using SequenceInputStream, in my app I just merge MP3 files in one and play it using the JNI Library MPG123, but I tested the file using MediaPlayer without problems.
This code isn't the best, but it works...
private void mergeSongs(File mergedFile,File...mp3Files){
FileInputStream fisToFinal = null;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mergedFile);
fisToFinal = new FileInputStream(mergedFile);
for(File mp3File:mp3Files){
if(!mp3File.exists())
continue;
FileInputStream fisSong = new FileInputStream(mp3File);
SequenceInputStream sis = new SequenceInputStream(fisToFinal, fisSong);
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = fisSong.read(buf)) != -1;)
fos.write(buf, 0, readNum);
} finally {
if(fisSong!=null){
fisSong.close();
}
if(sis!=null){
sis.close();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fos!=null){
fos.flush();
fos.close();
}
if(fisToFinal!=null){
fisToFinal.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

How to get the file name of a file which is transferred via wifi direct in android?

I have seen an example about this question.But when I have a try on it , it just occur an error in this code File f = new File(Uri.parse(uri.toString())); and just say that Constructor File(Uri) is undefined . I have stucked in this error for many days. I don't know what's wrong with it because other people can work. The following is the suggested code
public class WiFiDirectBundle extends Serializable {
private String fileName;
private String mimeType;
private Long fileSize;
private byte[] fileContent;
public WiFiDirectBundle() {}
// adds a file to the bundle, given its URI
public void setFile(Uri uri) {
File f = new File(Uri.parse(uri.toString()));
fileName = f.getName();
mimeType = MimeTypeMap.getFileExtensionFromUrl(f.getAbsolutePath());
fileSize = f.length();
FileInputStream fin = new FileInputStream(f);
fileContent = new byte[(int) f.length()];
fin.read(fileContent);
}
// restores the file of the bundle, given its directory (change to whatever
// fits you better)
public String restoreFile(String baseDir) {
File f = new File(baseDir + "/" + fileName);
try {
FileOutputStream fos = new FileOutputStream(f);
if (fileContent != null) {
fos.write(fileContent);
}
fos.close();
return f.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public String getFileName() {
return fileName;
}
public String getMimeType() {
return mimeType;
}
public Long getFileSize() {
return fileSize;
}
}
And this is original qusetion:
How to find file name of a file which is transferred via wifi direct mode in android?
Also I am a beginner in Wifi Direct ,I can successfully link two device and transfer file ,but I want to linked more device and transfer file Sequentially can anyone give me some advices about learning it or some examples about how to do it.Thanks!
use
File f = new File(uri.getPath());
instead of
File f = new File(Uri.parse(uri.toString()));
to get file path from Uri
you can open inputstream of a file from its uri using content resolver
ContentResolver cr=getContentResolver();
InputStream in=cr.OpenInputStream(file_uri);
you can use this input stream to read from the file

Categories

Resources