webrtc 工具类

直接上代码;webrtc 工具类

package com.example.mqttdome;import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;import org.webrtc.AudioSource;
import org.webrtc.AudioTrack;
import org.webrtc.Camera1Enumerator;
import org.webrtc.Camera2Enumerator;
import org.webrtc.CameraVideoCapturer;
import org.webrtc.DataChannel;
import org.webrtc.DefaultVideoDecoderFactory;
import org.webrtc.DefaultVideoEncoderFactory;
import org.webrtc.EglBase;
import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnection;
import org.webrtc.PeerConnectionFactory;
import org.webrtc.RtpReceiver;
import org.webrtc.ScreenCapturerAndroid;
import org.webrtc.SessionDescription;
import org.webrtc.SurfaceTextureHelper;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoDecoderFactory;
import org.webrtc.VideoEncoderFactory;
import org.webrtc.VideoSource;
import org.webrtc.VideoTrack;import java.util.ArrayList;public class WebRTCUtils {private static final String TAG = "webrtc_utils";private final PeerConnectionFactory factory;private final PeerConnection peer;private final EglBase.Context eglBaseContext;private final SurfaceTextureHelper surfaceTextureHelper;private final VideoCapturer camera;private final AudioTrack audioTrack;private VideoTrack videoTrack;private OnWebRtcListener webRtcListener;public EglBase.Context getEglBaseContext() {return eglBaseContext;}public void setWebRtcListener(OnWebRtcListener webRtcListener) {this.webRtcListener = webRtcListener;}public VideoTrack getVideoTrack() {return videoTrack;}public WebRTCUtils(Context context, Intent data) {eglBaseContext = EglBase.create().getEglBaseContext();surfaceTextureHelper = SurfaceTextureHelper.create("SurfaceTextureHelper_jason", eglBaseContext);PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();VideoEncoderFactory enc = new DefaultVideoEncoderFactory(eglBaseContext, true, false);VideoDecoderFactory dec = new DefaultVideoDecoderFactory(eglBaseContext);PeerConnectionFactory.initialize(PeerConnectionFactory.InitializationOptions.builder(context).createInitializationOptions());factory = PeerConnectionFactory.builder().setOptions(options).setVideoDecoderFactory(dec).setVideoEncoderFactory(enc).createPeerConnectionFactory();ArrayList<PeerConnection.IceServer> iceServers = new ArrayList<>();iceServers.add(PeerConnection.IceServer.builder("stun:stun3.l.google.com:19302").createIceServer());peer = factory.createPeerConnection(iceServers, new PeerObserver() {@Overridepublic void onIceCandidate(IceCandidate iceCandidate) {super.onIceCandidate(iceCandidate);webRtcListener.onIceCandidate(iceCandidate);}@Overridepublic void onAddStream(MediaStream mediaStream) {super.onAddStream(mediaStream);webRtcListener.onAddStream(mediaStream);}});AudioSource audioSource = factory.createAudioSource(new MediaConstraints());audioTrack = factory.createAudioTrack("jason_audio_track", audioSource);camera = createCameraDevices(true, context);if (camera != null) {VideoSource videoSource = factory.createVideoSource(camera.isScreencast());camera.initialize(surfaceTextureHelper, context, videoSource.getCapturerObserver());videoTrack = factory.createVideoTrack("VideoTrack_jason", videoSource);}MediaStream stream = factory.createLocalMediaStream("jason_stream");stream.addTrack(audioTrack);if (videoTrack != null)stream.addTrack(videoTrack);if (peer != null)peer.addStream(stream);// start captureif (camera != null)camera.startCapture(640, 360, 25);Log.i(TAG, "WebRTCUtils: camera:" + camera);}public void createOffer() {if (peer == null)return;peer.createOffer(new SdpObserver() {@Overridepublic void onCreateSuccess(SessionDescription sessionDescription) {super.onCreateSuccess(sessionDescription);peer.setLocalDescription(new SdpObserver(), sessionDescription);// send sdpString description = sessionDescription.description;webRtcListener.onSdpSendRemoteOffer(description);Log.i(TAG, "onCreateSuccess: sdp:" + description);}}, new MediaConstraints());}public void receiveOffer(String sdp) {if (peer == null)return;peer.setRemoteDescription(new SdpObserver(), new SessionDescription(SessionDescription.Type.OFFER, sdp));peer.createAnswer(new SdpObserver() {@Overridepublic void onCreateSuccess(SessionDescription sessionDescription) {super.onCreateSuccess(sessionDescription);peer.setLocalDescription(new SdpObserver(), sessionDescription);// send back sdpString description = sessionDescription.description;webRtcListener.onSdpSendRemoteAnswer(description);Log.i(TAG, "onCreateSuccess: sdp back:" + description);}}, new MediaConstraints());}public void saveAnswer(String sdp) {if (peer == null)return;Log.i(TAG, "saveAnswer: " + sdp);peer.setRemoteDescription(new SdpObserver(), new SessionDescription(SessionDescription.Type.ANSWER, sdp));}public void saveCandidate(int lineIndex, String mid, String candidate) {if (peer == null)return;Log.i(TAG, "saveCandidate: " + candidate);peer.addIceCandidate(new IceCandidate(mid,lineIndex,candidate));}public void release() {try {if (camera != null)camera.stopCapture();} catch (Exception e) {Log.i(TAG, "release: error:" + e.getMessage());}if (audioTrack!=null)audioTrack.setEnabled(false);if (videoTrack!=null)videoTrack.setEnabled(false);if (peer!=null){peer.close();peer.dispose();}factory.dispose();surfaceTextureHelper.dispose();}// -----------------------------------------------------------------------------------------工具类public interface OnWebRtcListener {void onIceCandidate(IceCandidate iceCandidate);void onAddStream(MediaStream mediaStream);void onSdpSendRemoteOffer(String sdp);void onSdpSendRemoteAnswer(String sdp);}private static class PeerObserver implements PeerConnection.Observer {@Overridepublic void onSignalingChange(PeerConnection.SignalingState signalingState) {}@Overridepublic void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {}@Overridepublic void onIceConnectionReceivingChange(boolean b) {}@Overridepublic void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {}@Overridepublic void onIceCandidate(IceCandidate iceCandidate) {}@Overridepublic void onIceCandidatesRemoved(IceCandidate[] iceCandidates) {}@Overridepublic void onAddStream(MediaStream mediaStream) {}@Overridepublic void onRemoveStream(MediaStream mediaStream) {}@Overridepublic void onDataChannel(DataChannel dataChannel) {}@Overridepublic void onRenegotiationNeeded() {}@Overridepublic void onAddTrack(RtpReceiver rtpReceiver, MediaStream[] mediaStreams) {}}private static class SdpObserver implements org.webrtc.SdpObserver {@Overridepublic void onCreateSuccess(SessionDescription sessionDescription) {}@Overridepublic void onSetSuccess() {}@Overridepublic void onCreateFailure(String s) {}@Overridepublic void onSetFailure(String s) {}}public static void startCaptor(Activity activity) {MediaProjectionManager manager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);if (manager == null) {Log.i(TAG, "startCaptor: manager is null");return;}Intent intent = manager.createScreenCaptureIntent();activity.startActivityForResult(intent, 119);}public static VideoCapturer createCameraDevices(boolean isFront, Context context) {Camera2Enumerator camera2Enumerator = new Camera2Enumerator(context);String[] deviceNames1 = camera2Enumerator.getDeviceNames();for (String item : deviceNames1) {if (isFront ? camera2Enumerator.isFrontFacing(item) : camera2Enumerator.isBackFacing(item)) {CameraVideoCapturer cameraVideoCapturer = camera2Enumerator.createCapturer(item, null);if (cameraVideoCapturer != null){Log.i(TAG, "createCameraDevices: use camera 2 ");Toast.makeText(context, "camera 2", Toast.LENGTH_LONG).show();return cameraVideoCapturer;}}}Camera1Enumerator enumerator = new Camera1Enumerator(false);final String[] deviceNames = enumerator.getDeviceNames();// First, try to find front facing camerafor (String deviceName : deviceNames) {if (isFront ? enumerator.isFrontFacing(deviceName) : enumerator.isBackFacing(deviceName)) {VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);if (videoCapturer != null) {Log.i(TAG, "createCameraDevices: use camera 1 ");Toast.makeText(context, "camera 1", Toast.LENGTH_LONG).show();return videoCapturer;}}}return null;}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/214215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

API低代码开发平台的实际应用及好处

API低代码开发平台是一种快速开发工具&#xff0c;可以帮助企业快速构建和部署应用程序&#xff0c;并提供易于使用的API集成。 实际应用 API低代码开发平台的应用范围非常广泛&#xff0c;包括但不限于以下几个方面&#xff1a; 企业级应用程序开发&#xff1a;API低代码开发…

TypeScript中的类型缩小、类型谓词

一. 概览 TypeScript中的类型缩小的方式有typeof、in等方式进行类型缩小。 二. 类型缩小 typeof function test(a: string| number | string []) {if(a) {if(typeof a string) {} else if(typeof a number) {}} }in关键字 nterface ISideBar {hide: () >void }interf…

mybatis-plus查询的字段和mysql关键字重名

先看一下这个 TableField("show") 这个注解表示当前属性对应在数据库的字段为show&#xff0c;但是show在mysql中为关键字&#xff0c;直接查询会导致语法错误 正确写法应该是 但写sql由和mybatis-plus理念相违背&#xff0c; 并且无法轻松创建对应方法&#xff0…

第8课 SQL入门之使用数据处理函数

文章目录 8.1 函数8.2 使用函数8.2.1 文本处理函数8.2.2 日期和时间处理函数8.2.3 数值处理函数 表8-3 常用数值处理函数 这一课介绍什么是函数&#xff0c;DBMS支持何种函数&#xff0c;以及如何使用这些函数&#xff1b;还将讲解为什么SQL函数的使用可能会带来问题。 8.1 函数…

数据结构之----逻辑结构、物理结构

数据结构之----逻辑结构、物理结构 目前我们常见的数据结构分别有&#xff1a; 数组、链表、栈、队列、哈希表、树、堆、图 而它们可以从 逻辑结构和物理结构两个维度进行分类。 什么是逻辑结构&#xff1f; 逻辑结构是指数据元素之间的逻辑关系&#xff0c;而逻辑结构又分为…

HCIA-H12-811题目解析(5)

1、【单选题】 以下关于Hybrid端口说法正确的有&#xff1f; 2、【单选题】使用命令"vlan batch 10 20"和"valn batch 10 to 20"&#xff0c;分别能创建的vlan数量是&#xff1f;&#xff08;&#xff09; 3、【单选题】二层ACL的编号范围是&#xff1f;…

Scala日志log4j,序列化Gson

一、日志输出log4j 1. Scala中配置log4j依赖 对于 Maven 项目,可以在 pom.xml 文件中添加以下内容: <dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version> </dependency>2.创建…

VueUse工具库

VueUse VueUse不是Vue.use&#xff0c;它是为Vue 2和3服务的一套Vue Composition API的常用工具集&#xff0c;是目前世界上Star最高的同类型库之一。它的初衷就是将一切原本并不支持响应式的JS API变得支持响应式&#xff0c;省去程序员自己写相关代码。 VueUse 是一个基于 …

Java毕业设计 SSM SpringBoot 在线学习系统

Java毕业设计 SSM SpringBoot 在线学习系统 SSM SpringBoot 在线学习系统 功能介绍 首页 图片轮播 视频推荐 在线学习 学习介绍 评论 收藏 资料中心 资料详情 下载资料 话题讨论 文档发布 试题中心 系统公告 登录 注册学生 个人中心 试题记录 错题本 我的收藏 算法演示 结果分…

C语言 害死人不偿命的(3n+1)算法 挖掘机技术哪家强 选择排序 贪心算法

1.害死人不偿命的&#xff08;3n1)算法 卡拉兹( Calatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把(3n1)砍掉一半。这样一直反复砍下去,最后一定在某一步得到n1。卡拉兹在1950年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员…

持续集成交付CICD:Jenkins使用GitLab共享库实现前后端项目Sonarqube

目录 一、实验 1.Jenkins使用GitLab共享库实现后端项目Sonarqube 2.优化GitLab共享库 3.Jenkins使用GitLab共享库实现前端项目Sonarqube 4.Jenkins通过插件方式进行优化 二、问题 1.sonar-scanner 未找到命令 2.npm 未找到命令 一、实验 1.Jenkins使用GitLab共享库实现…

Vue学习笔记-Vue3中ref和reactive函数的使用

前言 为了让vue3中的数据变成响应式&#xff0c;需要使用ref,reactive函数 ref函数使用方式 导入ref函数 import {ref} from vue在setup函数中&#xff0c;将需要响应式的数据通过ref函数进行包装&#xff0c;修改响应式数据时&#xff0c;需要通过: ref包装的响应式对象.val…

Flink之迟到的数据

迟到数据的处理 推迟水位线推进: WatermarkStrategy.<Event>forBoundedOutOfOrderness(Duration.ofSeconds(2))设置窗口延迟关闭&#xff1a;.allowedLateness(Time.seconds(3))使用侧流接收迟到的数据: .sideOutputLateData(lateData) public class Flink12_LateDataC…

力扣编程题算法初阶之双指针算法+代码分析

目录 第一题&#xff1a;复写零 第二题&#xff1a;快乐数&#xff1a; 第三题&#xff1a;盛水最多的容器 第四题&#xff1a;有效三角形的个数 第一题&#xff1a;复写零 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 思路&#xff1a; 上期…

【SpringBoot教程】SpringBoot 统一异常处理(附核心工具类-ErrorInfoBuilder)

作者简介&#xff1a;大家好&#xff0c;我是撸代码的羊驼&#xff0c;前阿里巴巴架构师&#xff0c;现某互联网公司CTO 联系v&#xff1a;sulny_ann&#xff08;17362204968&#xff09;&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗…

曲线分板机主轴有何特点?如何选择合适的曲线分板机主轴?

在现代工业领域&#xff0c;分板机主轴作为重要的机械部件&#xff0c;其性能和质量对于生产效率和产品质量具有至关重要的影响。而在这其中&#xff0c;曲线分板机主轴则因为其独特的优势而被广泛应用于PCB电路板的切割和分板。面对市场上众多的曲线分板机主轴品牌&#xff0c…

【深度学习】loss与梯度与交叉熵的关系

问的GPT3.5 模型训练时loss与梯度的关系&#xff1f; 在深度学习模型训练过程中&#xff0c;loss&#xff08;损失函数&#xff09;与梯度&#xff08;gradient&#xff09;之间存在密切关系。损失函数衡量模型在给定输入上的预测输出与实际输出之间的差距&#xff0c;而梯度则…

Leetcode 2958. Length of Longest Subarray With at Most K Frequency

Leetcode 2958. Length of Longest Subarray With at Most K Frequency 1. 解题思路2. 代码实现 题目链接&#xff1a;2958. Length of Longest Subarray With at Most K Frequency 1. 解题思路 这一题思路上其实也很简单&#xff0c;就是一个滑动窗口的思路&#xff0c;遍历…

前端知识(十三)——JavaScript监听按键,禁止F12,禁止右键,禁止保存网页【Ctrl+s】等操作

禁止右键 document.oncontextmenu new Function("event.returnValuefalse;") //禁用右键禁止按键 // 监听按键 document.onkeydown function () {// f12if (window.event && window.event.keyCode 123) {alert("F12被禁用");event.keyCode 0…

RNN循环神经网络python实现

import collections import math import re import random import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2ldef read_txt():# 读取文本数据with open(./A Study in Drowning.txt, r, encodingutf-8) as f:# 读取每一行l…