Android-WebRTC-双人视频

这篇具有很好参考价值的文章主要介绍了Android-WebRTC-双人视频。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

省略开启本机摄像头的过程
以下和WebSocket通信的时候,是通过Gson转对象为字符串的方式传输的数据文章来源地址https://www.toymoban.com/news/detail-601080.html

  • 整个过程
    Android-WebRTC-双人视频,space,android,webrtc,实时视频,java
  • layout_rtc.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/dp_20"
    >

    <org.webrtc.SurfaceViewRenderer
        android:id="@+id/localView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintHeight_percent="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <org.webrtc.SurfaceViewRenderer
        android:id="@+id/remoteView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintHeight_percent="0.5"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        />

</androidx.constraintlayout.widget.ConstraintLayout>
  • RtcActivity
package com.dream.app.activity;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.Nullable;

import com.dream.app.adapter.PeerConnectionAdapter;
import com.dream.app.adapter.SdpAdapter;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.webrtc.Camera1Enumerator;
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.SessionDescription;
import org.webrtc.SurfaceTextureHelper;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoSource;
import org.webrtc.VideoTrack;

import java.lang.reflect.Type;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.Random;

public class RtcActivity extends Activity {

    private static final String TAG = "RtcRemoteActivity";

    private WebSocketClient webSocketClient = null;
    private PeerConnection peerConnection = null;
    private static final Type sessionDescriptionType = new TypeToken<SessionDescription>(){}.getType();
    private static final Type iceCandidateType = new TypeToken<IceCandidate>(){}.getType();
    private VideoTrack videoTrack;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rtc);

        //  factory static init
        PeerConnectionFactory.initialize(PeerConnectionFactory.InitializationOptions
                .builder(this)
                .createInitializationOptions());
        EglBase.Context eglBaseContext = EglBase.create().getEglBaseContext();
        PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();

        //  create video encoder/decoder
        DefaultVideoEncoderFactory defaultVideoEncoderFactory =
                new DefaultVideoEncoderFactory(eglBaseContext, true, true); // encoder
        DefaultVideoDecoderFactory defaultVideoDecoderFactory =
                new DefaultVideoDecoderFactory(eglBaseContext); // decoder

        //  factory create
        PeerConnectionFactory peerConnectionFactory = PeerConnectionFactory.builder()
                .setOptions(options)
                .setVideoEncoderFactory(defaultVideoEncoderFactory)
                .setVideoDecoderFactory(defaultVideoDecoderFactory)
                .createPeerConnectionFactory();

        // create videoCapturer
        Camera1Enumerator camera1Enumerator = new Camera1Enumerator(false);// false输出到surface
        String[] deviceNames = camera1Enumerator.getDeviceNames();
        VideoCapturer videoCapturer = null;
        for (String deviceName : deviceNames) {
            if (camera1Enumerator.isFrontFacing(deviceName)) {
                VideoCapturer capturer = camera1Enumerator.createCapturer(deviceName, null);
                if (capturer != null) {
                    videoCapturer = capturer;
                    break;
                }
                Log.e(TAG, "onCreate: create capturer fail");
                return;
            }
        }
        if (videoCapturer == null) {
            Log.e(TAG, "onCreate: create capturer fail");
            return;
        }

        //  create videoSource
        VideoSource videoSource = peerConnectionFactory.createVideoSource(videoCapturer.isScreencast());

        //  init videoCapturer
        SurfaceTextureHelper surfaceTextureHelper = SurfaceTextureHelper.create("surfaceTexture", eglBaseContext);
        videoCapturer.initialize(surfaceTextureHelper, this, videoSource.getCapturerObserver());
        videoCapturer.startCapture(480, 640, 30);// width, height, frame

        //  create videoTrack
        videoTrack = peerConnectionFactory.createVideoTrack("videoTrack-1", videoSource);

        //  get show view
        SurfaceViewRenderer localView = findViewById(R.id.localView);
        localView.setMirror(true);// 镜像
        localView.init(eglBaseContext, null);

        //  link track to view so that data show in view
        videoTrack.addSink(localView);

        Activity activity = this;

        // link websocket
        try {
            String uriStr = "ws://host/webrtc/" + Math.abs(new Random().nextInt()) % 100;
            Log.e(TAG, "onCreate: " + uriStr);
            webSocketClient = new WebSocketClient(new URI(uriStr)) {
                @Override
                public void onOpen(ServerHandshake handshakedata) {
                    //  create peerConnection
                    peerConnection = peerConnectionFactory.createPeerConnection(Collections.singletonList(PeerConnection.IceServer
                            .builder("turn:host:3478")
                            .setUsername("admin")
                            .setPassword("123456")
                            .createIceServer()), new PeerConnectionAdapter() {

                        @Override
                        public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {
                            super.onIceGatheringChange(iceGatheringState);
                            Log.e(TAG, "onIceGatheringChange: " + iceGatheringState);
                        }

                        @Override
                        public void onIceCandidate(IceCandidate iceCandidate) {
                            super.onIceCandidate(iceCandidate);
                            //TODO send to remote the local iceCandidate
                            Log.e(TAG, "onIceCandidate: ICE CANDIDATE");
                            webSocketClient.send(new Gson().toJson(iceCandidate, iceCandidateType));
                        }

                        @Override
                        public void onAddStream(MediaStream mediaStream) { // turn deal with
                            super.onAddStream(mediaStream);
                            Log.e(TAG, "onAddStream: ICE STREAM");
                            //  get remote videoTrack
                            VideoTrack remoteVideoTrack = mediaStream.videoTracks.get(0);
                            runOnUiThread(() -> {
                                SurfaceViewRenderer remoteView = findViewById(R.id.remoteView);
                                remoteView.setMirror(false);
                                remoteView.init(eglBaseContext, null);
                                //  link track to view so that data show in view
                                remoteVideoTrack.addSink(remoteView);
                            });
                        }
                    });

                    if (peerConnection == null) {
                        Log.e(TAG, "onCreate: peerConnection fail");
                        webSocketClient.close();
                        activity.finish();
                    }

                    //  create stream
                    MediaStream stream = peerConnectionFactory.createLocalMediaStream("stream");
                    stream.addTrack(videoTrack);
                    peerConnection.addStream(stream);
                }

                @Override
                public void onMessage(String message) {
                    Log.e(TAG, "onMessage: " + message);

                    /**
                     * SDP change
                     */
                    if ("offer".equals(message)) {
                        // peerConnection offer
                        peerConnection.createOffer(new SdpAdapter("offer") {
                            @Override
                            public void onCreateSuccess(SessionDescription sessionDescription) {
                                super.onCreateSuccess(sessionDescription);
                                peerConnection.setLocalDescription(new SdpAdapter("local set local sd"), sessionDescription);

                                //TODO send sessionDescription to remote
                                webSocketClient.send("offer-" + new Gson().toJson(sessionDescription, sessionDescriptionType));
                            }
                        }, new MediaConstraints());
                        return;
                    }
                    if (message.startsWith("answer-")) {

                        peerConnection.setRemoteDescription(new SdpAdapter()
                                , new Gson().fromJson(message.substring("answer-".length()), sessionDescriptionType));
                        peerConnection.createAnswer(new SdpAdapter() {
                            @Override
                            public void onCreateSuccess(SessionDescription sessionDescription) {
                                super.onCreateSuccess(sessionDescription);

                                Log.e(TAG, "onCreateSuccess: createAnswer");

                                peerConnection.setLocalDescription(new SdpAdapter(), sessionDescription);
                                // send local sd to call
                                webSocketClient.send("answer-offer-" + new Gson().toJson(sessionDescription, sessionDescriptionType));
                            }

                            @Override
                            public void onCreateFailure(String s) {
                                super.onCreateFailure(s);
                                Log.e(TAG, "onCreateFailure: fail " + s);
                            }

                        }, new MediaConstraints());
                        return;
                    }
                    if (message.startsWith("offer-receiver-")) {
                        peerConnection.setRemoteDescription(new SdpAdapter()
                                , new Gson().fromJson(message.substring("offer-receiver-".length()), sessionDescriptionType));
                        return;
                    }
                    // ------------------------ sdp change -----------------------------------

                    /**
                     * ICE change
                     */
                    // get remote IceCandidate
                    IceCandidate remoteIceCandidate = new Gson().fromJson(message, iceCandidateType);
                    peerConnection.addIceCandidate(remoteIceCandidate);
                    // ------------------------ ice change -----------------------------------
                }

                @Override
                public void onClose(int code, String reason, boolean remote) {

                }

                @Override
                public void onError(Exception ex) {
                    ex.printStackTrace();
                }
            };
        } catch (URISyntaxException e) {
            Log.e(TAG, "onCreate: ", e);
            return;
        }
        webSocketClient.connect();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (webSocketClient.isOpen()) {
            webSocketClient.close();
            webSocketClient = null;
        }
        if (peerConnection != null) {
            peerConnection.dispose();
            peerConnection = null;
        }
        if (videoTrack != null) {
            videoTrack.dispose();
            videoTrack = null;
        }
    }
}

到了这里,关于Android-WebRTC-双人视频的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android开源计划-一周开发app,webrtc音视频开发

    题目 – 一周开发app计划 首批参与成员 -小巫 -墨香 -梦痕 -边城刀客 -徐cc 要求 – -每位认领者按照开源规范来做,代码规范和Android开发规范 -每位认领者必须拥有github账号,熟练使用git对代码进来管理 -每个人认领一个功能点或模块 -提出完善的解决方案并提供封装良好的库

    2024年04月08日
    浏览(35)
  • Android WebRtc+SRS/ZLM视频通话(1):虚拟机安装Ubuntu

    来自奔三人员的焦虑日志 秉着没事找事的原则,这里直接从服务器安装开始说起,也当记录自己这一路以来的愚昧之举,由于没有物理服务器,这里以虚拟机为例进行操作。 下载并安装虚拟机软件。建议使用 VMware 或 VirtualBox,它们是免费的虚拟机软件,我这里下的是VMware,

    2024年02月03日
    浏览(36)
  • Android webrtc实战(一)录制本地视频并播放,附带详细的基础知识讲解

    目录 一、创建PeerConnectionFactory 初始化 构建对象 二、创建AudioDeviceModule AudioDeviceModule JavaAudioDeviceModule 构建对象 setAudioAttributes setAudioFormat setAudioSource 创建录制视频相关对象 创建VideoSource 创建VideoCapturer 创建VideoTrack 播放视频 切换前后置摄像头 别忘了申请权限 完整代码 本系列

    2024年02月16日
    浏览(42)
  • 视频直播新时代,低延时直播交互,Web,Android,WebRtc推流拉流测试

    直播现在已经深入了生活,学习,工作和娱乐方方面面,由于前些年的技术所限,传统rtmp,flv,m3u8 技术让直播快速启动项目产品,但也有很多不足,特别的交互式直播,一直是其中的痛点,延时较大(1-10秒不等) 让用户即想用,已不是太爽,随技术进步,Webrtc已经切入了视

    2024年01月19日
    浏览(46)
  • Android平台一对一音视频通话方案对比:WebRTC VS RTMP VS RTSP

    一对一音视频通话使用场景 一对一音视频通话都需要稳定、清晰和流畅,以确保良好的用户体验,常用的使用场景如下: 社交应用 :社交应用是一种常见的使用场景,用户可以通过音视频通话进行面对面的交流; 在线教育: 老师和学生可以通过音视频通话功能进行实时互

    2024年02月13日
    浏览(35)
  • Webrtc android的编译步骤

    首先下载depot_tools 按官方教程来 https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up 这步骤操作完后会产生这两个目录 首先运行下一些相关依赖 Generate projects using GN. Make sure your current working directory is src/ of your workspace. Then run: You can

    2024年02月09日
    浏览(37)
  • WebRTC 系列(二、本地通话,H5、Android、iOS)

    有了上一篇 WebRTC 简介的基础,我们知道了 WebRTC 的工作流程,接下来就是需要用代码去实现这个流程了。对于不同端,实现起来的难易程度可能略微不同(实践中我感觉 iOS 端是资料最少的),但是整体流程是一样的。 问:要把大象装冰箱,总共分几步?答:三步。 初始化

    2024年02月11日
    浏览(31)
  • 国内镜像:极速下载编译WebRTC源码(For Android/Linux/IOS)(二十四)

    简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏: Audio工程师进阶系列 【 原创干货持续更新中…… 】🚀 优质专栏: 多媒体系统工程师系列 【 原创干货持续更新中…… 】🚀 人生格言: 人生从来没有捷径

    2024年01月17日
    浏览(47)
  • uniapp开发WebRTC语音直播间支持app(android+IOS)和H5,并记录了所有踩得坑

    1. 创建自己的语音直播间 2. 查询所有直播间列表 3.加入房间 4.申请上位 5.麦克风控制 6.声音控制 7.赠送礼物(特效 + 批量移动动画) 8.退出房间 1.uniapp 实现客户端H5、安卓、苹果 2.webRTC实现语音直播间(具体原理网上有很多文章我就不讲了,贴个图) 3.使用node.js搭建信令服

    2024年02月19日
    浏览(32)
  • WebRTC音视频通话-WebRTC视频自定义RTCVideoCapturer相机

    WebRTC音视频通话-WebRTC视频自定义RTCVideoCapturer相机 在之前已经实现了WebRTC调用ossrs服务,实现直播视频通话功能。但是在使用过程中,RTCCameraVideoCapturer类提供的方法不能修改及调节相机的灯光等设置,那就需要自定义RTCVideoCapturer自行采集画面了。 iOS端WebRTC调用ossrs相关,实现

    2024年02月12日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包