Обработка видео на андроиде, как записать данные MPEG4 в файл MP4?

Как записать (обернуть) данные MPEG4 в файл MP4 в Android?

Я делаю какую-то обработку видео на платформе Android, но я не знаю, как записать обработанные данные (закодированные в каком-то стандарте, например, MPEG4) обратно в видео файл, такой как mp4. Я думаю, что для этого лучше всего использовать API, но я не могу найти необходимый API.

У кого-нибудь есть идеи?

3 ответа

mp4parser может работать только с полностью созданными потоковыми кадрами, вы не можете писать кадр за кадром. Поправьте меня если я ошибаюсь

H264TrackImpl h264Track = new H264TrackImpl(new BufferedInputStream(some input stream here));
Movie m = new Movie();
IsoFile out = new DefaultMp4Builder().build(m);
File file = new File("/sdcard/encoded.mp4");
FileOutputStream fos = new FileOutputStream(file);
out.getBox(fos.getChannel());
fos.close();

Теперь нам нужно знать, как писать кадр за кадром.

OpenCV может быть слишком сложным для работы, но я не могу придумать ничего проще. OpenCV - это библиотека компьютерного зрения, которая предлагает API для C, C++ и Python.

Поскольку вы используете Android, вам нужно будет загрузить оболочку Java для OpenCV с именем JavaCV, и это сторонний API. Я написал небольшой пост с инструкциями по установке OpenCV/JavaCV в Windows и использовании его с Netbeans, но в конце вам придется искать учебник, в котором показано, как установить OpenCV/JavaCV для платформы Android.

Это пример C++, который показывает, как открыть входное видео и скопировать кадры в выходной файл. Но поскольку вы используете Android, пример использования JavaCV лучше, поэтому следующий код копирует кадры из входного видео и записывает его в выходной файл с именем out.mp4:

package opencv_videowriter;

import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;

public class OpenCV_videowriter 
{
    public static void main(String[] args) 
    {
        CvCapture capture = cvCreateFileCapture("cleanfish47.mp4");
        if (capture == null)
        {
            System.out.println("!!! Failed cvCreateFileCapture");
            return;
        }

        int fourcc_code = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FOURCC);
        double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
        int w = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
        int h = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

        CvVideoWriter writer = cvCreateVideoWriter("out.mp4",       // filename
                                                    fourcc_code,    // video codec
                                                    fps,            // fps
                                                    cvSize(w, h),   // video dimensions
                                                    1);             // is colored
        if (writer == null) 
        {
            System.out.println("!!! Failed cvCreateVideoWriter");

            return;
        }


        IplImage captured_frame = null;        
        while (true)
        {
            // Retrieve frame from the input file
            captured_frame = cvQueryFrame(capture);
            if (captured_frame == null)
            {
                System.out.println("!!! Failed cvQueryFrame");
                break;
            }


            // TODO: write code to process the captured frame (if needed)


            // Store frame in output file
            if (cvWriteFrame(writer, captured_frame) == 0) 
            {
                System.out.println("!!! Failed cvWriteFrame");
                break;
            }

        }

        cvReleaseCapture(capture);
        cvReleaseVideoWriter(writer);        
    }
}

Примечание: кадры в OpenCV хранят пиксели в порядке BGR.

Ваш вопрос не имеет смысла на 100%. MPEG-4 - это семейство спецификаций (все ISO/IEC 14496-*), а MP4 - это формат файлов, указанный в ISO/IEC 14496-14.

Если вы хотите создать файл MP4 из необработанного потока AAC и / или H264, я бы предложил использовать библиотеку mp4parser. Есть пример, который показывает, как объединить AAC и H264 в файл MP4.

// Full working solution:
// 1. Add to app/build.gradle -> implementation 'com.googlecode.mp4parser:isoparser:1.1.22'
// 2. Add to your code:
try {
    File mpegFile = new File(); // ... your mpeg file ;
    File mp4file = new File(); // ... you mp4 file;
    DataSource channel = new FileDataSourceImpl(mpegFile);
    IsoFile isoFile = new IsoFile(channel);
    List<TrackBox> trackBoxes = isoFile.getMovieBox().getBoxes(TrackBox.class);
    Movie movie = new Movie();
    for (TrackBox trackBox : trackBoxes) {
        movie.addTrack(new Mp4TrackImpl(channel.toString()
                + "[" + trackBox.getTrackHeaderBox().getTrackId() + "]", trackBox));
    }
    movie.setMatrix(isoFile.getMovieBox().getMovieHeaderBox().getMatrix());
    Container out = new DefaultMp4Builder().build(movie);

    FileChannel fc = new FileOutputStream(mp4file).getChannel();

    out.writeContainer(fc);
    fc.close();
    isoFile.close();
    channel.close();

    Log.d("TEST", "file mpeg " + mpegFile.getPath() + " was changed to " + mp4file.getPath());

    // mpegFile.delete(); // if you wish!

} catch (Exception e) {
    e.printStackTrace();
}

// It's all! Happy coding =)
Другие вопросы по тегам