前景:项目需要闲暇开发结合公司业务需求 因业务需求量不大未接入融合通信之类的付费 开发一款VR带摄像头眼镜 远程指挥调度 web播放 目前只做到实时播放音视频 未双方通信
作为一个java开发工程师 android 真是难为我 还好能看懂直接写过一些 多数借鉴于 http://www.tangokk.com
Android 思路:调取摄像头录屏实施推流
第一步:打开摄像头
try { cameraDevice = Camera.open(); } catch (Exception e){ Log.e(LOG_TAG, "camera open fail, if it's occupied by other applications"); finish(); return; }
第二步:录制实时推送到服务器
class CameraView extends SurfaceView implements SurfaceHolder.Callback, PreviewCallback { private SurfaceHolder mHolder; private Camera mCamera; public CameraView(Context context, Camera camera) { super(context); Log.w("camera", "camera view"); mCamera = camera; mHolder = getHolder(); mHolder.addCallback(CameraView.this); mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); mCamera.setPreviewCallback(CameraView.this); mCamera.setDisplayOrientation(90); } @Override public void surfaceCreated(SurfaceHolder holder) { try { stopPreview(); mCamera.setPreviewDisplay(holder); } catch (IOException exception) { mCamera.release(); mCamera = null; } } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { stopPreview(); Camera.Parameters camParams = mCamera.getParameters(); List<Camera.Size> sizes = camParams.getSupportedPreviewSizes(); // Sort the list in ascending order Collections.sort(sizes, new Comparator<Camera.Size>() { public int compare(final Camera.Size a, final Camera.Size b) { return a.width * a.height - b.width * b.height; } }); // Pick the first preview size that is equal or bigger, or pick the last (biggest) option if we cannot // reach the initial settings of imageWidth/imageHeight. for (int i = 0; i < sizes.size(); i++) { if ((sizes.get(i).width >= imageWidth && sizes.get(i).height >= imageHeight) || i == sizes.size() - 1) { imageWidth = sizes.get(i).width; imageHeight = sizes.get(i).height; Log.v(LOG_TAG, "Changed to supported resolution: " + imageWidth + "x" + imageHeight); break; } } camParams.setPreviewSize(imageWidth, imageHeight); Log.v(LOG_TAG, "Setting imageWidth: " + imageWidth + " imageHeight: " + imageHeight + " frameRate: " + frameRate); camParams.setPreviewFrameRate(frameRate); Log.v(LOG_TAG, "Preview Framerate: " + camParams.getPreviewFrameRate()); mCamera.setParameters(camParams); // Set the holder (which might have changed) again try { mCamera.setPreviewDisplay(holder); mCamera.setPreviewCallback(CameraView.this); startPreview(); } catch (Exception e) { Log.e(LOG_TAG, "Could not set preview display in surfaceChanged"); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { try { mHolder.addCallback(null); mCamera.setPreviewCallback(null); } catch (RuntimeException e) { // The camera has probably just been released, ignore. } } public void startPreview() { if (!isPreviewOn && mCamera != null) { isPreviewOn = true; mCamera.startPreview(); } } public void stopPreview() { if (isPreviewOn && mCamera != null) { isPreviewOn = false; mCamera.stopPreview(); } } @Override public void onPreviewFrame(byte[] data, Camera camera) { if (audioRecord == null || audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING) { startTime = System.currentTimeMillis(); return; } if (RECORD_LENGTH > 0) { int i = imagesIndex++ % images.length; yuvImage = images[i]; timestamps[i] = 1000 * (System.currentTimeMillis() - startTime); } /* get video data */ if (yuvImage != null && recording) { ((ByteBuffer) yuvImage.image[0].position(0)).put(data); if (RECORD_LENGTH <= 0) try { Log.v(LOG_TAG, "Writing Frame"); long t = 1000 * (System.currentTimeMillis() - startTime); if (t > recorder.getTimestamp()) { recorder.setTimestamp(t); } recorder.record(yuvImage); } catch (FFmpegFrameRecorder.Exception e) { Log.v(LOG_TAG, e.getMessage()); e.printStackTrace(); } } } } }
后端接流播放:2022年了rtmp不能播放了难受 而且目前来看大多数都没有好的解决方案 要不然就是技术封闭 付费挡道。
效果图
电脑能够播放但是多数浏览器不知道rtmp 码流只能切换其他码流 如ws之类的 感兴趣的同学可以一起来
qq 1552138571 邮箱1552138571@qq.com
目前使用的nginx + nginx-rtmp 现在正在更改码流转化接入java 使用 springboot接收 用cmd 来操作 ffmpeg 目前还为完成转换
标签:码流,Web,Log,sizes,mCamera,imageHeight,imageWidth,播放,public From: https://www.cnblogs.com/Javawang/p/16876337.html