0

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)"
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
David J
  • 129
  • 2
  • 8
  • 4
    Welcome to SO, please be a bit more specific when asking question: what have you tried, what do you expect, etc. See [how to ask](http://stackoverflow.com/help/how-to-ask) – Nehal Feb 29 '16 at 05:03
  • Welcome to SO. If you are looking for a code-factory or a learning site, then you have landed to the wrong place. – Phantômaxx Feb 29 '16 at 07:45
  • The error `PixelAspectRatioBox cannot be cast to sampleentries.codec.CodecSpecificBox` suggests that you are using the wrong variable type as a parameter at one point, wherever your line 62 in file VideoTrack.java is. – Gerald Schneider Feb 29 '16 at 10:11

1 Answers1

0

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.

Kinjal
  • 1,195
  • 4
  • 13
  • 24
wngxao
  • 72
  • 5
  • Besides ,you can only run these code in Android 4.2 or higher. – wngxao Feb 29 '16 at 08:34
  • Sorry, I'm new here.I don't know much the rule.I'm changing.I won't. – wngxao Feb 29 '16 at 08:59
  • Sorry, I am new in StackOverflow. I am not code-requestor. Actually I just to realize this function using JAVE JAR on Windows platform. but it did not worker in Android. So I just want an idea or method to realize it on Android. Sorry for my poor english. – David J Feb 29 '16 at 09:56