Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
283 views
in Technique[技术] by (71.8m points)

converter - How do I extractor audio to mp3 from mp4 using java in Android?

I want convert mp4 video to mp3 audio file in Android platform? How can I do it? Actually I test some JAR. Firstly, the JAAD lib be used to test.

import java.io.File;
import java.io.RandomAccessFile;
import java.util.List;

import net.sourceforge.jaad.aac.Decoder;
import net.sourceforge.jaad.aac.SampleBuffer;
import net.sourceforge.jaad.mp4.MP4Container;
import net.sourceforge.jaad.mp4.api.AudioTrack;
import net.sourceforge.jaad.mp4.api.Frame;
import net.sourceforge.jaad.mp4.api.Movie;
import net.sourceforge.jaad.mp4.api.Track;
import net.sourceforge.jaad.util.wav.WaveFileWriter;

public class Main2 {
    public static void main(String[] args) {
    System.out.println("dfd");
    try {
        decodeMP4("C:/a/input.mp4","./out.wav");
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println("over");

}
private static void decodeMP4(String in, String out) throws Exception {
    WaveFileWriter wav = null;
    try {
        final MP4Container cont = new MP4Container(new RandomAccessFile(in, "r"));
        final Movie movie = cont.getMovie();
        final List<Track> tracks = movie.getTracks(AudioTrack.AudioCodec.AAC);
        if(tracks.isEmpty()) throw new Exception("movie does not contain any AAC track");
        final AudioTrack track = (AudioTrack) tracks.get(0);

        wav = new WaveFileWriter(new File(out), track.getSampleRate(), track.getChannelCount(), track.getSampleSize());

        final Decoder dec = new Decoder(track.getDecoderSpecificInfo());

        Frame frame;
        final SampleBuffer buf = new SampleBuffer();
        while(track.hasMoreFrames()) {
            frame = track.readNextFrame();
            dec.decodeFrame(frame.getData(), buf);
            wav.write(buf.getData());
        }
    }
    finally {
        if(wav!=null) wav.close();
    }
}
}

but it throws an error

"java.lang.ClassCastException: net.sourceforge.jaad.mp4.boxes.impl.PixelAspectRatioBox cannot be cast to net.sourceforge.jaad.mp4.boxes.impl.sampleentries.codec.CodecSpecificBox
    at net.sourceforge.jaad.mp4.api.VideoTrack.<init>(VideoTrack.java:62)
    at net.sourceforge.jaad.mp4.api.Movie.createTrack(Movie.java:65)
    at net.sourceforge.jaad.mp4.api.Movie.<init>(Movie.java:46)
    at net.sourceforge.jaad.mp4.MP4Container.getMovie(MP4Container.java:134)
    at Main2.decodeMP4(Main2.java:30)
    at Main2.main(Main2.java:18)"
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This question is a little too complex. I know how to implement it. here is the code to extract audio data from video file ,but it's PCM data ,not mp3:

 public class AudioFromVideo{
    private String audio,video;
    private MediaCodec amc;
    private MediaExtractor ame;
    private MediaFormat amf;
    private String amime;
    public AudioFromVideo(String srcVideo,String destAudio){
        this.audio=destAudio;
        this.video=srcVideo;
        ame=new MediaExtractor();
        init();
    }
    public void init(){
            try {
                ame.setDataSource(video);
                amf=ame.getTrackFormat(1);
                ame.selectTrack(1);
                amime=amf.getString(MediaFormat.KEY_MIME);
                amc=MediaCodec.createDecoderByType(amime);
                amc.configure(amf, null, null, 0);
                amc.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
    public void start(){
        new AudioService(amc,ame,audio).start();
    }
    private class AudioService extends Thread{
        private MediaCodec amc;
        private MediaExtractor ame;
        private ByteBuffer[] aInputBuffers,aOutputBuffers;
        private String destFile;
        @SuppressWarnings("deprecation")
        AudioService(MediaCodec amc,MediaExtractor ame,String destFile){
            this.amc=amc;
            this.ame=ame;
            this.destFile=destFile;
            aInputBuffers=amc.getInputBuffers();
            aOutputBuffers=amc.getOutputBuffers();
        }
        @SuppressWarnings("deprecation")
        public void run(){
            try {
                OutputStream os=new FileOutputStream(new File(destFile));
                long count=0;
                while(true){
                        int inputIndex=amc.dequeueInputBuffer(0);
                        if(inputIndex==-1){
                            continue;
                        }
                        int sampleSize=ame.readSampleData(aInputBuffers[inputIndex], 0);
                        if(sampleSize==-1)break;
                        long presentationTime=ame.getSampleTime();
                        int flag=ame.getSampleFlags();
                        ame.advance();
                        amc.queueInputBuffer(inputIndex, 0, sampleSize, presentationTime, flag);
                        BufferInfo info=new BufferInfo();
                        int outputIndex=amc.dequeueOutputBuffer(info, 0);
                        if (outputIndex >= 0) {
                            byte[] data=new byte[info.size];
                            aOutputBuffers[outputIndex].get(data, 0, data.length);
                            aOutputBuffers[outputIndex].clear();
                            os.write(data);
                            count+=data.length;
                            Log.i("write", ""+count);
                            amc.releaseOutputBuffer(outputIndex, false);
                        } else if (outputIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                            aOutputBuffers = amc.getOutputBuffers();
                        } else if (outputIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {}
                }
                os.flush();
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

For example ,to extract audio data from Video file video.mp4,and save the extracted date into file audio.pcm,write code like this:

String videoPath=PATH+"/video.mp4";
String audioPath=PATH+"/audio.pcm";
new AudioFromVideo(video.audio).start();

If you need mp3 data,you can use lame mp3 lib to encode PCM data to MP3 format.I have all the code. but it is not convinent to paste all of them here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...