Android camera2 api galaxy s7

寵の児 提交于 2019-12-05 00:01:03

问题


I am writing an app which records video from the phone and uploads it to a server. Works fine on any device except Galaxy S7. On the Galaxy S7 recording produces a video file with audio only and either no video or one video frame. This is true in the temporary file created on the phone and not just the one uploaded to the server. I am using the Camera2 API, and I have tried with the front and back cameras.

I have tried with my code, and these two example applications: https://developer.android.com/samples/Camera2Video/project.html https://github.com/googlesamples/android-Camera2Video/blob/master/Application/src/main/java/com/example/android/camera2video/Camera2VideoFragment.java

The video file produced appears to be ok, here is the codec info: Stream 0 Type: Video Codec: H264 - MPEG-4 AVC (part 10) (avc1) Language: English Resolution: 960x720 Display resolution: 960x720 Frame rate: 29.055091

Stream 1 Type: Audio Codec: MPEG AAC Audio (mp4a) Language: English Channels: Stereo Sample rate: 16000 Hz


回答1:


After several days of work I found the answer.

The Samsung Galaxy S7 (and S6 I think) has a bug which messes up the encoding. The fix is to reencode using the function below.

Note that you need this dependency in your gradle: compile 'com.googlecode.mp4parser:isoparser:1.1.22'

    public void fixSamsungBug()
{
    DataSource channel = null;
    try
    {
        channel = new FileDataSourceImpl(app.dataMgr.videoFileURL);
    } catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }

    IsoFile isoFile = null;

    try
    {
        isoFile = new IsoFile(channel);
    } catch (IOException e)
    {
        e.printStackTrace();
    }

    List<TrackBox> trackBoxes = isoFile.getMovieBox().getBoxes(TrackBox.class);
    boolean sampleError = false;
    for (TrackBox trackBox : trackBoxes) {
        TimeToSampleBox.Entry firstEntry = trackBox.getMediaBox().getMediaInformationBox().getSampleTableBox().getTimeToSampleBox().getEntries().get(0);

        // Detect if first sample is a problem and fix it in isoFile
        // This is a hack. The audio deltas are 1024 for my files, and video deltas about 3000
        // 10000 seems sufficient since for 30 fps the normal delta is about 3000
        if(firstEntry.getDelta() > 10000) {
            sampleError = true;
            firstEntry.setDelta(3000);
        }
    }

    if(sampleError) {
        Log.d("gpinterviewandroid", "Sample error! correcting...");
        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);

        //delete file first!
        File file = new File(app.dataMgr.videoFileURL);
        boolean deleted = file.delete();


        FileChannel fc = null;
        try
        {
            //fc = new FileOutputStream(new File(app.dataMgr.videoFileURL)).getChannel();
            fc = new RandomAccessFile(app.dataMgr.videoFileURL, "rw").getChannel();
        } catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }

        try
        {
            out.writeContainer(fc);
            fc.close();
        } catch (IOException e)
        {
            e.printStackTrace();
        }

        Log.d("gpinterviewandroid", "Finished correcting raw video");
    }
}


来源:https://stackoverflow.com/questions/45358247/android-camera2-api-galaxy-s7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!