parent
083c306d2b
commit
d4b5956a81
Binary file not shown.
Binary file not shown.
@ -0,0 +1,224 @@ |
||||
|
||||
#include "include/lame/lame.h" |
||||
#include <jni.h> |
||||
|
||||
lame_global_flags *glf; |
||||
|
||||
lame_global_flags *initializeDefault(JNIEnv *env) { |
||||
lame_global_flags *glf = lame_init(); |
||||
lame_init_params(glf); |
||||
return glf; |
||||
} |
||||
|
||||
lame_global_flags *initialize( |
||||
JNIEnv *env, |
||||
jint inSamplerate, jint outChannel, |
||||
jint outSamplerate, jint outBitrate, jfloat scaleInput, jint mode, jint vbrMode, |
||||
jint quality, jint vbrQuality, jint abrMeanBitrate, jint lowpassFreq, jint highpassFreq, |
||||
jstring id3tagTitle, jstring id3tagArtist, jstring id3tagAlbum, |
||||
jstring id3tagYear, jstring id3tagComment) { |
||||
|
||||
lame_global_flags *glf = lame_init(); |
||||
lame_set_in_samplerate(glf, inSamplerate); |
||||
lame_set_num_channels(glf, outChannel); |
||||
lame_set_out_samplerate(glf, outSamplerate); |
||||
lame_set_brate(glf, outBitrate); |
||||
lame_set_quality(glf, quality); |
||||
lame_set_scale(glf, scaleInput); |
||||
lame_set_VBR_q(glf, vbrQuality); |
||||
lame_set_VBR_mean_bitrate_kbps(glf, abrMeanBitrate); |
||||
lame_set_lowpassfreq(glf, lowpassFreq); |
||||
lame_set_highpassfreq(glf, highpassFreq); |
||||
|
||||
switch (mode) { |
||||
case 0: |
||||
lame_set_mode(glf, STEREO); |
||||
break; |
||||
case 1: |
||||
lame_set_mode(glf, JOINT_STEREO); |
||||
break; |
||||
case 3: |
||||
lame_set_mode(glf, MONO); |
||||
break; |
||||
case 4: |
||||
lame_set_mode(glf, NOT_SET); |
||||
break; |
||||
default: |
||||
lame_set_mode(glf, NOT_SET); |
||||
break; |
||||
} |
||||
|
||||
switch (vbrMode) { |
||||
case 0: |
||||
lame_set_VBR(glf, vbr_off); |
||||
break; |
||||
case 2: |
||||
lame_set_VBR(glf, vbr_rh); |
||||
break; |
||||
case 3: |
||||
lame_set_VBR(glf, vbr_abr); |
||||
break; |
||||
case 4: |
||||
lame_set_VBR(glf, vbr_mtrh); |
||||
break; |
||||
case 6: |
||||
lame_set_VBR(glf, vbr_default); |
||||
break; |
||||
default: |
||||
lame_set_VBR(glf, vbr_off); |
||||
break; |
||||
|
||||
} |
||||
|
||||
|
||||
const jchar *title = NULL; |
||||
const jchar *artist = NULL; |
||||
const jchar *album = NULL; |
||||
const jchar *year = NULL; |
||||
const jchar *comment = NULL; |
||||
if (id3tagTitle) { |
||||
title = (*env)->GetStringChars(env, id3tagTitle, NULL); |
||||
} |
||||
if (id3tagArtist) { |
||||
artist = (*env)->GetStringChars(env, id3tagArtist, NULL); |
||||
} |
||||
if (id3tagAlbum) { |
||||
album = (*env)->GetStringChars(env, id3tagAlbum, NULL); |
||||
} |
||||
if (id3tagYear) { |
||||
year = (*env)->GetStringChars(env, id3tagYear, NULL); |
||||
} |
||||
if (id3tagComment) { |
||||
comment = (*env)->GetStringChars(env, id3tagComment, NULL); |
||||
} |
||||
|
||||
if (title || artist || album || year || comment) { |
||||
id3tag_init(glf); |
||||
|
||||
if (title) { |
||||
id3tag_set_title(glf, (const char *) title); |
||||
(*env)->ReleaseStringChars(env, id3tagTitle, title); |
||||
} |
||||
if (artist) { |
||||
id3tag_set_artist(glf, (const char *) artist); |
||||
(*env)->ReleaseStringChars(env, id3tagArtist, artist); |
||||
} |
||||
if (album) { |
||||
id3tag_set_album(glf, (const char *) album); |
||||
(*env)->ReleaseStringChars(env, id3tagAlbum, album); |
||||
} |
||||
if (year) { |
||||
id3tag_set_year(glf, (const char *) year); |
||||
(*env)->ReleaseStringChars(env, id3tagYear, year); |
||||
} |
||||
if (comment) { |
||||
id3tag_set_comment(glf, (const char *) comment); |
||||
(*env)->ReleaseStringChars(env, id3tagComment, comment); |
||||
} |
||||
} |
||||
|
||||
lame_init_params(glf); |
||||
|
||||
|
||||
return glf; |
||||
} |
||||
|
||||
jint encode( |
||||
JNIEnv *env, lame_global_flags *glf, |
||||
jshortArray buffer_l, jshortArray buffer_r, |
||||
jint samples, jbyteArray mp3buf) { |
||||
jshort *j_buffer_l = (*env)->GetShortArrayElements(env, buffer_l, NULL); |
||||
|
||||
jshort *j_buffer_r = (*env)->GetShortArrayElements(env, buffer_r, NULL); |
||||
|
||||
const jsize mp3buf_size = (*env)->GetArrayLength(env, mp3buf); |
||||
jbyte *j_mp3buf = (*env)->GetByteArrayElements(env, mp3buf, NULL); |
||||
|
||||
int result = lame_encode_buffer(glf, j_buffer_l, j_buffer_r, |
||||
samples, j_mp3buf, mp3buf_size); |
||||
|
||||
(*env)->ReleaseShortArrayElements(env, buffer_l, j_buffer_l, 0); |
||||
(*env)->ReleaseShortArrayElements(env, buffer_r, j_buffer_r, 0); |
||||
(*env)->ReleaseByteArrayElements(env, mp3buf, j_mp3buf, 0); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
jint encodeBufferInterleaved( |
||||
JNIEnv *env, lame_global_flags *glf, |
||||
jshortArray pcm, jint samples, jbyteArray mp3buf) { |
||||
jshort *j_pcm = (*env)->GetShortArrayElements(env, pcm, NULL); |
||||
|
||||
const jsize mp3buf_size = (*env)->GetArrayLength(env, mp3buf); |
||||
jbyte *j_mp3buf = (*env)->GetByteArrayElements(env, mp3buf, NULL); |
||||
|
||||
int result = lame_encode_buffer_interleaved(glf, j_pcm, |
||||
samples, j_mp3buf, mp3buf_size); |
||||
|
||||
(*env)->ReleaseShortArrayElements(env, pcm, j_pcm, 0); |
||||
(*env)->ReleaseByteArrayElements(env, mp3buf, j_mp3buf, 0); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
jint flush( |
||||
JNIEnv *env, lame_global_flags *glf, |
||||
jbyteArray mp3buf) { |
||||
const jsize mp3buf_size = (*env)->GetArrayLength(env, mp3buf); |
||||
jbyte *j_mp3buf = (*env)->GetByteArrayElements(env, mp3buf, NULL); |
||||
|
||||
int result = lame_encode_flush(glf, j_mp3buf, mp3buf_size); |
||||
|
||||
(*env)->ReleaseByteArrayElements(env, mp3buf, j_mp3buf, 0); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
void close_lame(lame_global_flags *glf) { |
||||
lame_close(glf); |
||||
glf = NULL; |
||||
} |
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_frank_ffmpeg_AudioPlayer_lameInitDefault |
||||
(JNIEnv *env, jclass jclazz) { |
||||
|
||||
glf = initializeDefault(env); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_com_frank_ffmpeg_AudioPlayer_lameInit( |
||||
JNIEnv *env, jclass cls, jint inSampleRate, jint outChannel, |
||||
jint outSampleRate, jint outBitrate, jfloat scaleInput, jint mode, jint vbrMode, |
||||
jint quality, jint vbrQuality, jint abrMeanBitrate, jint lowPassFreq, jint highPassFreq, |
||||
jstring id3tagTitle, jstring id3tagArtist, jstring id3tagAlbum, |
||||
jstring id3tagYear, jstring id3tagComment) { |
||||
|
||||
glf = initialize(env, inSampleRate, outChannel, outSampleRate, outBitrate, scaleInput, mode, |
||||
vbrMode, |
||||
quality, vbrQuality, abrMeanBitrate, lowPassFreq, highPassFreq, id3tagTitle, |
||||
id3tagArtist, id3tagAlbum, |
||||
id3tagYear, |
||||
id3tagComment); |
||||
} |
||||
|
||||
JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_AudioPlayer_lameEncode( |
||||
JNIEnv *env, jclass cls, jshortArray buffer_l, |
||||
jshortArray buffer_r, jint samples, jbyteArray mp3buf) { |
||||
return encode(env, glf, buffer_l, buffer_r, samples, mp3buf); |
||||
} |
||||
|
||||
JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_AudioPlayer_encodeBufferInterleaved( |
||||
JNIEnv *env, jclass cls, jshortArray pcm, |
||||
jint samples, jbyteArray mp3buf) { |
||||
return encodeBufferInterleaved(env, glf, pcm, samples, mp3buf); |
||||
} |
||||
|
||||
JNIEXPORT jint JNICALL Java_com_frank_ffmpeg_AudioPlayer_lameFlush( |
||||
JNIEnv *env, jclass cls, jbyteArray mp3buf) { |
||||
return flush(env, glf, mp3buf); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_com_frank_ffmpeg_AudioPlayer_lameClose( |
||||
JNIEnv *env, jclass cls) { |
||||
close_lame(glf); |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,340 @@ |
||||
package com.frank.ffmpeg.mp3; |
||||
|
||||
import android.annotation.TargetApi; |
||||
import android.media.MediaCodec; |
||||
import android.media.MediaCodec.BufferInfo; |
||||
import android.media.MediaExtractor; |
||||
import android.media.MediaFormat; |
||||
import android.os.Build; |
||||
import android.util.Log; |
||||
|
||||
import java.io.BufferedOutputStream; |
||||
import java.io.File; |
||||
import java.io.FileOutputStream; |
||||
import java.io.IOException; |
||||
import java.nio.ByteBuffer; |
||||
import java.nio.ByteOrder; |
||||
import java.nio.ShortBuffer; |
||||
import java.util.concurrent.BlockingDeque; |
||||
import java.util.concurrent.LinkedBlockingDeque; |
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) |
||||
public class Mp3Converter { |
||||
|
||||
private final static String TAG = Mp3Converter.class.getSimpleName(); |
||||
|
||||
private MediaCodec mMediaCodec; |
||||
private MediaExtractor mediaExtractor; |
||||
private BufferInfo bufferInfo; |
||||
private ByteBuffer[] rawInputBuffers; |
||||
private ByteBuffer[] encodedOutputBuffers; |
||||
private int inSampleRate; |
||||
private int channels; |
||||
|
||||
private final static int DEFAULT_QUEUE_SIZE = 512; |
||||
private BlockingDeque<BufferEncoded> writeQueue = new LinkedBlockingDeque<>(DEFAULT_QUEUE_SIZE); |
||||
private BlockingDeque<BufferDecoded> encodeQueue = new LinkedBlockingDeque<>(DEFAULT_QUEUE_SIZE); |
||||
private byte[] mp3buf; |
||||
|
||||
private boolean decodeFinished; |
||||
private boolean encodeFinished; |
||||
|
||||
private long readSize; |
||||
private long decodeSize; |
||||
private long encodeSize; |
||||
|
||||
private Mp3Lame mp3Lame; |
||||
private WriteThread writeThread; |
||||
private EncodeThread encodeThread; |
||||
private long lastPts; |
||||
|
||||
private class BufferDecoded { |
||||
int channels; |
||||
short[] leftBuffer; |
||||
short[] rightBuffer; |
||||
short[] pcm; |
||||
long pts; |
||||
} |
||||
|
||||
private class BufferEncoded { |
||||
byte[] buffer; |
||||
int length; |
||||
} |
||||
|
||||
private class WriteThread extends Thread { |
||||
|
||||
private String mp3Path; |
||||
private FileOutputStream fos; |
||||
private BufferedOutputStream bos; |
||||
|
||||
WriteThread(String path) { |
||||
super(); |
||||
mp3Path = path; |
||||
} |
||||
|
||||
@Override |
||||
public void run() { |
||||
try { |
||||
Log.i(TAG, "WriteThread start"); |
||||
|
||||
fos = new FileOutputStream(new File(mp3Path)); |
||||
bos = new BufferedOutputStream(fos, 200 * 1024); |
||||
|
||||
while (true) { |
||||
if (encodeFinished && writeQueue.size() == 0) { |
||||
break; |
||||
} |
||||
|
||||
BufferEncoded buffer = null; |
||||
try { |
||||
buffer = writeQueue.take(); |
||||
} catch (InterruptedException e) { |
||||
Log.e(TAG, "WriteThread InterruptedException=" + e.toString()); |
||||
} |
||||
|
||||
if(buffer != null) { |
||||
bos.write(buffer.buffer, 0, buffer.length); |
||||
} |
||||
} |
||||
bos.flush(); |
||||
bos.close(); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} finally { |
||||
try { |
||||
bos.flush(); |
||||
bos.close(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
Log.i(TAG, "WriteThread end"); |
||||
} |
||||
} |
||||
|
||||
private class EncodeThread extends Thread { |
||||
@Override |
||||
public void run() { |
||||
Log.i(TAG, "EncodeThread start"); |
||||
|
||||
while (true) { |
||||
if (decodeFinished && encodeQueue.size() == 0) { |
||||
break; |
||||
} |
||||
BufferDecoded buffer = null; |
||||
try { |
||||
buffer = encodeQueue.take(); |
||||
} catch (InterruptedException e) { |
||||
Log.e(TAG, "EncodeThread InterruptedException=" + e.toString()); |
||||
} |
||||
if (buffer != null) { |
||||
encodeToMp3(buffer); |
||||
} |
||||
} |
||||
encodeFinished = true; |
||||
|
||||
writeThread.interrupt(); |
||||
|
||||
Log.i(TAG, "EncodeThread end"); |
||||
} |
||||
} |
||||
|
||||
private class DecodeThread extends Thread { |
||||
@Override |
||||
public void run() { |
||||
long startTime = System.currentTimeMillis(); |
||||
try { |
||||
Log.i(TAG, "DecodeThread start"); |
||||
|
||||
while (true) { |
||||
int outputBufIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, -1); |
||||
if (outputBufIndex >= 0) { |
||||
ByteBuffer buffer = encodedOutputBuffers[outputBufIndex]; |
||||
decodeSize += bufferInfo.size; |
||||
ShortBuffer shortBuffer = buffer.order(ByteOrder.nativeOrder()).asShortBuffer(); |
||||
|
||||
short[] leftBuffer = null; |
||||
short[] rightBuffer = null; |
||||
short[] pcm = null; |
||||
|
||||
if (channels == 2) { |
||||
pcm = new short[shortBuffer.remaining()]; |
||||
shortBuffer.get(pcm); |
||||
} else { |
||||
leftBuffer = new short[shortBuffer.remaining()]; |
||||
rightBuffer = leftBuffer; |
||||
shortBuffer.get(leftBuffer); |
||||
Log.e(TAG, "single channel leftBuffer.length = " + leftBuffer.length); |
||||
} |
||||
|
||||
buffer.clear(); |
||||
|
||||
BufferDecoded bufferDecoded = new BufferDecoded(); |
||||
bufferDecoded.leftBuffer = leftBuffer; |
||||
bufferDecoded.rightBuffer = rightBuffer; |
||||
bufferDecoded.pcm = pcm; |
||||
bufferDecoded.channels = channels; |
||||
bufferDecoded.pts = bufferInfo.presentationTimeUs; |
||||
encodeQueue.put(bufferDecoded); |
||||
|
||||
mMediaCodec.releaseOutputBuffer(outputBufIndex, false); |
||||
|
||||
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { |
||||
Log.e(TAG, "DecodeThread get BUFFER_FLAG_END_OF_STREAM"); |
||||
decodeFinished = true; |
||||
break; |
||||
} |
||||
} else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { |
||||
encodedOutputBuffers = mMediaCodec.getOutputBuffers(); |
||||
} else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { |
||||
final MediaFormat oformat = mMediaCodec.getOutputFormat(); |
||||
Log.d(TAG, "Output format has changed to " + oformat); |
||||
} |
||||
} |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
|
||||
encodeThread.interrupt(); |
||||
long endTime = System.currentTimeMillis(); |
||||
Log.i(TAG, "DecodeThread finished time=" + (endTime - startTime) / 1000); |
||||
} |
||||
} |
||||
|
||||
public void convertToMp3(String srcPath, String mp3Path) { |
||||
|
||||
long startTime = System.currentTimeMillis(); |
||||
long endTime; |
||||
|
||||
encodeThread = new EncodeThread(); |
||||
writeThread = new WriteThread(mp3Path); |
||||
DecodeThread decodeThread = new DecodeThread(); |
||||
|
||||
encodeThread.start(); |
||||
writeThread.start(); |
||||
prepareDecode(srcPath); |
||||
decodeThread.start(); |
||||
readSampleData(); |
||||
|
||||
try { |
||||
writeThread.join(); |
||||
} catch (InterruptedException e) { |
||||
Log.e(TAG, "convertToMp3 InterruptedException=" + e.toString()); |
||||
} |
||||
|
||||
double mReadSize = readSize / 1024.0 / 1024.0; |
||||
double mDecodeSize = decodeSize / 1024.0 / 1024.0; |
||||
double mEncodeSize = encodeSize / 1024.0 / 1024.0; |
||||
Log.i(TAG, "readSize=" + mReadSize + ", decodeSize=" + mDecodeSize + ",encodeSize=" + mEncodeSize); |
||||
|
||||
endTime = System.currentTimeMillis(); |
||||
Log.i(TAG, "convertToMp3 finish time=" + (endTime - startTime) / 1000); |
||||
} |
||||
|
||||
private void prepareDecode(String path) { |
||||
try { |
||||
mediaExtractor = new MediaExtractor(); |
||||
mediaExtractor.setDataSource(path); |
||||
for (int i = 0; i < mediaExtractor.getTrackCount(); i++) { |
||||
MediaFormat mMediaFormat = mediaExtractor.getTrackFormat(i); |
||||
Log.i(TAG, "prepareDecode get mMediaFormat=" + mMediaFormat); |
||||
|
||||
String mime = mMediaFormat.getString(MediaFormat.KEY_MIME); |
||||
if (mime.startsWith("audio")) { |
||||
mMediaCodec = MediaCodec.createDecoderByType(mime); |
||||
mMediaCodec.configure(mMediaFormat, null, null, 0); |
||||
mediaExtractor.selectTrack(i); |
||||
inSampleRate = mMediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE); |
||||
channels = mMediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT); |
||||
break; |
||||
} |
||||
} |
||||
mMediaCodec.start(); |
||||
|
||||
bufferInfo = new BufferInfo(); |
||||
rawInputBuffers = mMediaCodec.getInputBuffers(); |
||||
encodedOutputBuffers = mMediaCodec.getOutputBuffers(); |
||||
Log.i(TAG, "--channel=" + channels + "--sampleRate=" + inSampleRate); |
||||
|
||||
mp3Lame = new Mp3LameBuilder() |
||||
.setInSampleRate(inSampleRate) |
||||
.setOutChannels(channels) |
||||
.setOutBitrate(128) |
||||
.setOutSampleRate(inSampleRate) |
||||
.setQuality(9) |
||||
.setVbrMode(Mp3LameBuilder.VbrMode.VBR_MTRH) |
||||
.build(); |
||||
|
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
|
||||
private void readSampleData() { |
||||
boolean rawInputEOS = false; |
||||
|
||||
while (!rawInputEOS) { |
||||
for (int i = 0; i < rawInputBuffers.length; i++) { |
||||
int inputBufIndex = mMediaCodec.dequeueInputBuffer(-1); |
||||
if (inputBufIndex >= 0) { |
||||
ByteBuffer buffer = rawInputBuffers[inputBufIndex]; |
||||
int sampleSize = mediaExtractor.readSampleData(buffer, 0); |
||||
long presentationTimeUs = 0; |
||||
if (sampleSize < 0) { |
||||
rawInputEOS = true; |
||||
sampleSize = 0; |
||||
} else { |
||||
readSize += sampleSize; |
||||
presentationTimeUs = mediaExtractor.getSampleTime(); |
||||
} |
||||
mMediaCodec.queueInputBuffer(inputBufIndex, 0, |
||||
sampleSize, presentationTimeUs, |
||||
rawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0); |
||||
if (!rawInputEOS) { |
||||
mediaExtractor.advance(); |
||||
} else { |
||||
break; |
||||
} |
||||
} else { |
||||
Log.e(TAG, "wrong inputBufIndex=" + inputBufIndex); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private void encodeToMp3(BufferDecoded buffer) { |
||||
|
||||
if (buffer == null || buffer.pts == lastPts) { |
||||
return; |
||||
} |
||||
lastPts = buffer.pts; |
||||
|
||||
int bufferLength = buffer.pcm.length / 2; |
||||
if (mp3buf == null) { |
||||
mp3buf = new byte[(int) (bufferLength * 1.25 + 7200)]; |
||||
} |
||||
if (bufferLength > 0) { |
||||
int bytesEncoded; |
||||
if (channels == 2) { |
||||
bytesEncoded = mp3Lame.encodeBufferInterLeaved(buffer.pcm, bufferLength, mp3buf); |
||||
}else { |
||||
bytesEncoded = mp3Lame.encode(buffer.leftBuffer, buffer.leftBuffer, bufferLength, mp3buf); |
||||
} |
||||
Log.d(TAG, "mp3Lame encodeSize=" + bytesEncoded); |
||||
|
||||
if (bytesEncoded > 0) { |
||||
BufferEncoded be = new BufferEncoded(); |
||||
be.buffer = mp3buf; |
||||
be.length = bytesEncoded; |
||||
try { |
||||
writeQueue.put(be); |
||||
} catch (InterruptedException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
encodeSize += bytesEncoded; |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,71 @@ |
||||
package com.frank.ffmpeg.mp3; |
||||
|
||||
import com.frank.ffmpeg.AudioPlayer; |
||||
|
||||
public class Mp3Lame { |
||||
|
||||
public Mp3Lame() { |
||||
AudioPlayer.lameInitDefault(); |
||||
} |
||||
|
||||
Mp3Lame(Mp3LameBuilder builder) { |
||||
initialize(builder); |
||||
} |
||||
|
||||
private void initialize(Mp3LameBuilder builder) { |
||||
AudioPlayer.lameInit(builder.inSampleRate, builder.outChannel, builder.outSampleRate, |
||||
builder.outBitrate, builder.scaleInput, getIntForMode(builder.mode), getIntForVbrMode(builder.vbrMode), builder.quality, builder.vbrQuality, builder.abrMeanBitrate, |
||||
builder.lowPassFreq, builder.highPassFreq, builder.id3tagTitle, builder.id3tagArtist, |
||||
builder.id3tagAlbum, builder.id3tagYear, builder.id3tagComment); |
||||
} |
||||
|
||||
public int encode(short[] buffer_l, short[] buffer_r, |
||||
int samples, byte[] mp3buf) { |
||||
|
||||
return AudioPlayer.lameEncode(buffer_l, buffer_r, samples, mp3buf); |
||||
} |
||||
|
||||
int encodeBufferInterLeaved(short[] pcm, int samples, |
||||
byte[] mp3buf) { |
||||
return AudioPlayer.encodeBufferInterleaved(pcm, samples, mp3buf); |
||||
} |
||||
|
||||
public int flush(byte[] mp3buf) { |
||||
return AudioPlayer.lameFlush(mp3buf); |
||||
} |
||||
|
||||
public void close() { |
||||
AudioPlayer.lameClose(); |
||||
} |
||||
|
||||
private static int getIntForMode(Mp3LameBuilder.Mode mode) { |
||||
switch (mode) { |
||||
case STEREO: |
||||
return 0; |
||||
case JSTEREO: |
||||
return 1; |
||||
case MONO: |
||||
return 3; |
||||
case DEFAULT: |
||||
return 4; |
||||
} |
||||
return -1; |
||||
} |
||||
|
||||
private static int getIntForVbrMode(Mp3LameBuilder.VbrMode mode) { |
||||
switch (mode) { |
||||
case VBR_OFF: |
||||
return 0; |
||||
case VBR_RH: |
||||
return 2; |
||||
case VBR_ABR: |
||||
return 3; |
||||
case VBR_MTRH: |
||||
return 4; |
||||
case VBR_DEFAUT: |
||||
return 6; |
||||
} |
||||
return -1; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,147 @@ |
||||
package com.frank.ffmpeg.mp3; |
||||
|
||||
public class Mp3LameBuilder { |
||||
|
||||
|
||||
public enum Mode { |
||||
STEREO, JSTEREO, MONO, DEFAULT |
||||
} |
||||
|
||||
public enum VbrMode { |
||||
VBR_OFF, VBR_RH, VBR_MTRH, VBR_ABR, VBR_DEFAUT |
||||
} |
||||
|
||||
|
||||
int inSampleRate; |
||||
int outSampleRate; |
||||
int outBitrate; |
||||
int outChannel; |
||||
public int quality; |
||||
int vbrQuality; |
||||
int abrMeanBitrate; |
||||
int lowPassFreq; |
||||
int highPassFreq; |
||||
float scaleInput; |
||||
Mode mode; |
||||
VbrMode vbrMode; |
||||
|
||||
String id3tagTitle; |
||||
String id3tagArtist; |
||||
String id3tagAlbum; |
||||
String id3tagComment; |
||||
String id3tagYear; |
||||
|
||||
Mp3LameBuilder() { |
||||
|
||||
this.id3tagTitle = null; |
||||
this.id3tagAlbum = null; |
||||
this.id3tagArtist = null; |
||||
this.id3tagComment = null; |
||||
this.id3tagYear = null; |
||||
|
||||
this.inSampleRate = 44100; |
||||
this.outSampleRate = 0; |
||||
this.outChannel = 2; |
||||
this.outBitrate = 128; |
||||
this.scaleInput = 1; |
||||
|
||||
this.quality = 5; |
||||
this.mode = Mode.DEFAULT; |
||||
this.vbrMode = VbrMode.VBR_OFF; |
||||
this.vbrQuality = 5; |
||||
this.abrMeanBitrate = 128; |
||||
|
||||
this.lowPassFreq = 0; |
||||
this.highPassFreq = 0; |
||||
} |
||||
|
||||
Mp3LameBuilder setQuality(int quality) { |
||||
this.quality = quality; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setInSampleRate(int inSampleRate) { |
||||
this.inSampleRate = inSampleRate; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setOutSampleRate(int outSampleRate) { |
||||
this.outSampleRate = outSampleRate; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setOutBitrate(int bitrate) { |
||||
this.outBitrate = bitrate; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setOutChannels(int channels) { |
||||
this.outChannel = channels; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setId3tagTitle(String title) { |
||||
this.id3tagTitle = title; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setId3tagArtist(String artist) { |
||||
this.id3tagArtist = artist; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setId3tagAlbum(String album) { |
||||
this.id3tagAlbum = album; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setId3tagComment(String comment) { |
||||
this.id3tagComment = comment; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setId3tagYear(String year) { |
||||
this.id3tagYear = year; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setScaleInput(float scaleAmount) { |
||||
this.scaleInput = scaleAmount; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setMode(Mode mode) { |
||||
this.mode = mode; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setVbrMode(VbrMode mode) { |
||||
this.vbrMode = mode; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setVbrQuality(int quality) { |
||||
this.vbrQuality = quality; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setAbrMeanBitrate(int bitrate) { |
||||
this.abrMeanBitrate = bitrate; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setLowpassFreqency(int freq) { |
||||
this.lowPassFreq = freq; |
||||
return this; |
||||
} |
||||
|
||||
Mp3LameBuilder setHighpassFreqency(int freq) { |
||||
this.highPassFreq = freq; |
||||
return this; |
||||
} |
||||
|
||||
Mp3Lame build() { |
||||
return new Mp3Lame(this); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue