#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);
}
}
}`