ARCore Захватывает Пользовательскую видеозапись | Перепробовал Все Решения

#webrtc #arcore #webrtc-android

Вопрос:

Цель состоит в том, чтобы разместить сцену arcore на webrtc

Ниже приведен код, который я использую для пользовательского видеоадаптера, но он не работает.

Показать ошибку:

sending message to a Handler on a dead thread

 
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.view.PixelCopy;
import android.view.SurfaceView;
import android.view.View;

import androidx.annotation.RequiresApi;


import org.webrtc.SurfaceTextureHelper;
import org.webrtc.VideoCapturer;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;


@RequiresApi(api = Build.VERSION_CODES.N)
public class ViewCapturer implements VideoCapturer,
        PixelCopy.OnPixelCopyFinishedListener {
    private static int VIEW_CAPTURER_FRAMERATE_MS = 10;

    private final View view;
    private Bitmap viewBitmap;
    private Handler handler = new Handler(Looper.getMainLooper());
    private Handler handlerPixelCopy = new Handler(Looper.getMainLooper());
//    private VideoCapturer.Listener videoCapturerListener;
    private AtomicBoolean started = new AtomicBoolean(false);

    public ViewCapturer(View view) {
        this(view, 24);
    }

    public ViewCapturer(View view, int framePerSecond) {
        if (framePerSecond <= 0)
            throw new IllegalArgumentException("framePersecond must be greater than 0");
        this.view = view;
        float tmp = (1f / framePerSecond) * 1000;
        VIEW_CAPTURER_FRAMERATE_MS = Math.round(tmp);
    }

    private final Runnable viewCapturer = new Runnable() {
        @Override
        public void run() {
            boolean dropFrame = view.getWidth() == 0 || view.getHeight() == 0;

            // Only capture the view if the dimensions have been established
            if (!dropFrame) {
                // Draw view into bitmap backed canvas
                int measuredWidth = View.MeasureSpec.makeMeasureSpec(view.getWidth(),
                        View.MeasureSpec.EXACTLY);
                int measuredHeight = View.MeasureSpec.makeMeasureSpec(view.getHeight(),
                        View.MeasureSpec.EXACTLY);
                view.measure(measuredWidth, measuredHeight);
                view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());

                viewBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
                try {
                    PixelCopy.request((SurfaceView) view, viewBitmap, ViewCapturer.this, handlerPixelCopy);
                } catch (IllegalArgumentException e) {
                }
            }
        }
    };

//    /**
//     * Returns the list of supported formats for this view capturer. Currently, only supports
//     * capturing to RGBA_8888 bitmaps.
//     *
//     * @return list of supported formats.
//     */
//    @Override
//    public List<VideoFormat> getSupportedFormats() {
//        List<VideoFormat> videoFormats = new ArrayList<>();
//        VideoDimensions videoDimensions = new VideoDimensions(view.getWidth(), view.getHeight());
//        VideoFormat videoFormat = new VideoFormat(videoDimensions, 30, VideoPixelFormat.RGBA_8888);
//
//        videoFormats.add(videoFormat);
//
//        return videoFormats;
//    }

    /**
     * Returns true because we are capturing screen content.
     */
    @Override
    public boolean isScreencast() {
        return true;
    }

    @Override
    public void initialize(SurfaceTextureHelper surfaceTextureHelper, Context context, CapturerObserver capturerObserver) {

    }

    @Override
    public void startCapture(int i, int i1, int i2) {
        this.started.set(true);

        // Notify capturer API that the capturer has started
        boolean capturerStarted = handler.postDelayed(viewCapturer,
                VIEW_CAPTURER_FRAMERATE_MS);
    }

    /**
     * Stop capturing frames. Note that the SDK cannot receive frames once this has been invoked.
     */
    @Override
    public void stopCapture() {
        this.started.set(false);
        handler.removeCallbacks(viewCapturer);
    }

    @Override
    public void changeCaptureFormat(int i, int i1, int i2) {

    }

    @Override
    public void dispose() {

    }

    @Override
    public void onPixelCopyFinished(int i) {

        // Extract the frame from the bitmap
        int bytes = viewBitmap.getByteCount();
        ByteBuffer buffer = ByteBuffer.allocate(bytes);
        viewBitmap.copyPixelsToBuffer(buffer);
        byte[] array = buffer.array();
        final long captureTimeNs = TimeUnit.MILLISECONDS.toNanos(SystemClock.elapsedRealtime());


        if (started.get()) {
            handler.postDelayed(viewCapturer, VIEW_CAPTURER_FRAMERATE_MS);
        }
    }
}`