【问题标题】:How do I extractor audio to mp3 from mp4 using java in Android?如何在 Android 中使用 java 将音频从 mp4 提取到 mp3?
【发布时间】:2016-06-12 01:29:40
【问题描述】:

我想在 Android 平台上将 mp4 视频转换为 mp3 音频文件? 我该怎么做? 实际上我测试了一些 JAR。 首先,使用JAAD lib进行测试。

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();
    }
}
}

但它会引发错误

"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)"

【问题讨论】:

  • 欢迎来到 SO,请在提问时更具体一点:您尝试过什么,您期望什么等。请参阅how to ask
  • 欢迎来到 SO。如果您正在寻找代码工厂或学习网站,那么您来错地方了。
  • 错误PixelAspectRatioBox cannot be cast to sampleentries.codec.CodecSpecificBox 表明您在某一时刻使用了错误的变量类型作为参数,无论您在文件 VideoTrack.java 中的第 62 行是什么位置。

标签: android converter media


【解决方案1】:

这个问题有点太复杂了。我知道如何实现它。 这是从视频文件中提取音频数据的代码,但它是 PCM 数据,而不是 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();
            }
        }
    }
}

例如,从视频文件video.mp4中提取音频数据,并将提取的日期保存到文件audio.pcm中,代码如下:

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

如果你需要 mp3 数据,你可以使用 lame mp3 lib 将 PCM 数据编码为 MP3 格式。我有所有的代码。但不方便将它们全部粘贴在这里。

【讨论】:

  • 此外,您只能在 Android 4.2 或更高版本中运行这些代码。
  • 对不起,我是新来的。我不太了解规则。我正在改变。我不会。
  • 对不起,我是 StackOverflow 的新手。我不是代码请求者。其实我只是在Windows平台上使用JAVE JAR来实现这个功能。但它不适用于Android。所以我只是想要一个想法或方法在Android上实现它。对不起我的英语不好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-11
  • 2021-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
相关资源
最近更新 更多