4

私がやりたいことは、Android プロジェクトの特定の時間に複数のオーディオ ファイルをビデオ ファイルにマージすることです。

たとえば、2 つのオーディオ ファイルがあるとします。5 秒の長さの a1、5 秒の長さの a2、および 20 秒の長さのビデオ V1 です。したがって、時間 00:01s から 00:05s でオーディオ a1 をビデオ V1 にマージし、時間 00:10s から 00:15s でオーディオ a2 をビデオ V1 にマージします。ここでの「マージ」とは、ビデオ ファイルが特定の時間にオーディオ ファイル a1 と a2 からナレーションを追加することを意味し、追加ではありません。

Google と StackOverflow を検索した結果、Mp4Parser ライブラリを見つけましたが、残念ながら、オーディオ トラックをビデオ トラックに完全にマージすることしかできません。私の質問は、特定の時間に複数のオーディオトラックからマージする方法ですか?

私が使用したコードは次のとおりです。

    public boolean mux(String videoFile, String audioFile, String outputFile) {
    Movie video;
    try {
        video = new MovieCreator().build(videoFile);
    } catch (RuntimeException e) {
        e.printStackTrace();
        return false;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }

    Movie audio;
    try {
        audio = new MovieCreator().build(audioFile);
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    } catch (NullPointerException e) {
        e.printStackTrace();
        return false;
    }
    Track audioTrack = audio.getTracks().get(0);
    List<Track> tracks = new ArrayList<Track>();
    tracks.add(video.getTracks().get(0));
    tracks.add(audioTrack);
    video.setTracks(tracks);
    Container out = new DefaultMp4Builder().build(video);
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(outputFile);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return false;
    }
    BufferedWritableFileByteChannel byteBufferByteChannel = new BufferedWritableFileByteChannel(fos);
    try {
        out.writeContainer(byteBufferByteChannel);
        byteBufferByteChannel.close();
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
    return true;
}

private static class BufferedWritableFileByteChannel implements WritableByteChannel {
    private static final int BUFFER_CAPACITY = 1000000;

    private boolean isOpen = true;
    private final OutputStream outputStream;
    private final ByteBuffer byteBuffer;
    private final byte[] rawBuffer = new byte[BUFFER_CAPACITY];

    private BufferedWritableFileByteChannel(OutputStream outputStream) {
        this.outputStream = outputStream;
        this.byteBuffer = ByteBuffer.wrap(rawBuffer);
    }

    @Override
    public int write(ByteBuffer inputBuffer) throws IOException {
        int inputBytes = inputBuffer.remaining();

        if (inputBytes > byteBuffer.remaining()) {
            dumpToFile();
            byteBuffer.clear();

            if (inputBytes > byteBuffer.remaining()) {
                throw new BufferOverflowException();
            }
        }

        byteBuffer.put(inputBuffer);

        return inputBytes;
    }

    @Override
    public boolean isOpen() {
        return isOpen;
    }

    @Override
    public void close() throws IOException {
        dumpToFile();
        isOpen = false;
    }
    private void dumpToFile() {
        try {
            outputStream.write(rawBuffer, 0, byteBuffer.position());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

どんな助けでも大歓迎です!本当にありがとう。

4

0 に答える 0