首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

【音视频通话】使用asp.net core 8+vue3 实现高效音视频通话

编程知识
2024年08月28日 11:24

引言

    在三年前,写智能小车的时候,当时小车上有一个摄像头需要采集,实现推拉流的操作,技术选型当时第一版用的是nginx的rtmp的推拉流,服务器的配置环境是centos,2H4G3M的一个配置,nginx的rtmp的延迟是20秒,超慢,后来研究了SRS以及ZLMediaKit这两个开源的推拉流服务器,没记错的话,两个都是基于c++开发的,性能都很棒,后来更换了推拉流服务器,小汽车的延迟在一秒不到,性能大幅度提升,当时研究了一下,然后没有记录,这次使用SRS实现了音视频通话,以及共享桌面的功能,特此记录以及分享给大家。

技术概览

    本demo总共涉及到三个服务,部署环境是腾讯云的轻量服务器,配置是2H2G3M的服务器,CENTOS系统,nginx部署前端,docker部署后端以及SRS服务。

    SRS 

      SRS是一个开源的(MIT协议)简单高效的实时视频服务器,支持RTMP、WebRTC、HLS、HTTP-FLV、SRT、MPEG-DASH和GB28181等协议。 SRS媒体服务器和FFmpeg、OBS、VLC、 WebRTC等客户端配合使用,提供流的接收和分发的能力,是一个典型的发布 (推流)和订阅(播放)服务器模型。 SRS支持互联网广泛应用的音视频协议转换,比如可以将RTMP或SRT, 转成HLS或HTTP-FLV或WebRTC等协议。

      后端

      后端是一个基于net8.0基础框架开发的一个webapi的接口,前后端通讯使用的是signalr,用来实现不同用户之间的一个消息更改通知,本项目没有涉及到任何数据库方面的。

 

 

    前端

      前端是基于node20.16.0,vue3。其中,推拉流的地址和后端服务器的地址配置在configjs.json中配置,pushUrl是推流的地址,pullUrl是拉流的地址,apiUrl是后端接口的地址,signalrUrl是用来做前后端websocket通讯的一个地址。在apiUrl和signalrUrl中的端口需要和上方的后端运行的端口保持一致才可以互相访问通讯,具体配置文档查看下方图例

 

功能概览

    总体功能分为一下几个:

    设备检测/参数设置 

      这个页码主要是用来配置摄像头,并且检测摄像头是否可用,音频检测音频是否可用,并且配置音频设备,后续的音视频通话都是根据此处选择的设备进行推拉流,用户名称,由于本项目是一个demo,所以都是基于内存,用户是自己设置之后,在demo中与人通讯的一个标识;在这个页面配置好视频设备,音频设备,以及用户名称,就可以去后续的页面进行群聊或者单聊,或者桌面共享的功能。    

    群聊  

      群聊进入到页面,就可以看到已经存在的群聊信息,以及在线人数,可以进行加入或者删除群聊的操作,如果有新增的群组,此处也会使用Signalr进行同步更新获取最新的群组列表数据,此demo没有判断删除的时候权限问题以及如果有人正在群聊删除群组的问题,在设备检测页面没有选择音视频设备,也可以进入群组,可以查看有音视频的在线人员的一个音视频,如图所示,在上方输入要创建的群组名称,点击添加群组即可到如下页面,进入视频页面,会先去推流到服务器,以便下一个进入的人可以看到你的视频流,同时如果没有选择音视频设备,点击加入也是如下页面,并且该页面不会展示群组的在线人,可以从视频的摄像头上方可以查看是哪个用户的音视频。

    单聊

       单聊就是只有两个人进行音视频通话,同时也支持没有选择设备可以进行通话,没有添加文字聊天的支持,单聊列表,也会使用signalr进行同步更新,在用户设置了用户名称之后,在这里就可以看到列表数据的更新。点击通话就可以和在线的人员进行音视频通话,同时不能和自己通话,且选择的人如果在处于单聊状态中,也无法进行音视频通话,在选择了要进行通话的用户后,会进入到聊天页面,同时对方用户会收到一个提醒,是否接受音视频通话,可以拒绝,也可以接受,拒绝之后,请求方会退出到在线列表的页面,点击接受会进入到双方的一个音视频通话的页面,可以进行语音聊天,可以看对方的摄像头推送的视频流。同时接受之后,任意一方离开聊天,另外一方也会直接退出聊天页面。返回到用户在线列表页面中。

    共享桌面 

      共享桌面的操作和群组的一样,在上方输入共享桌面的名称,点击按钮,即可进入到共享桌面的页面中去。进入到页面,会提示需要共享的屏幕内容,可选整个屏幕,浏览器或者窗口都可以,同时也可以选择是否要共享此页面的音频,点击分享之后,即可看到共享的视频内容,右侧显示了参与人列表,并且如果选择了音频设备,也会采集语音推送,多个参与人进行语音聊天,语音会显示谁在发言,收到了谁的语音流。同时当共享的人,点击了停止共享,其他参与人也可以共享自己的桌面,点击了共享桌面按钮,其他参与人的共享桌面按钮会隐藏,并且他们会看到采集的你的屏幕的视频信息。

 

 程序配置

    关于配置方面,主要是前端的配置以及SRS的配置,前端方面的配置,在刚开始已经阐述过,主要是SRS的推拉流的配置,以及API和Signalr的地址配置,如果服务器是外网, 地址必须是外网服务器的地址,关于SRS的配置,在下载好SRS之后,SRS提供了默认的配置文件夹,文件夹名字是叫conf文件夹,里面提供了各种不同功能的conf配置文件,此处我们基于console.conf进行改造,下面的是console.conf的配置信息,第一行是listen,默认是1935,代表SRS启动的时候的RMP的直播服务端口。max_connection代表最大连接数量,默认是1000,srs_log_tank是日志的打印方式,默认是console,即控制台,可选配置有file和console,file是文件的输出形式,如果是file的形式,必须通过配置srs_log_file参数配置日志的打印文件的路径,默认是.objs/srs.log的文件。daemon,代表的是是否以后台的形式运行,on代表开启,off代表关闭。http_api,SRS提供了一些api,这个配置代表是否开启http_api,并且端口是8080。下方,展示了SRS官网提供的API导航。rtc_server启用webrtc的功能,端口是udp的8000,默认是8000,其中最后一个配置是candidata,如果是本机部署,这个可以不需要配置,如果是需要部署在外网服务器,那这个就需要设置成外网的服务器地址。

    SRS的视频推拉流,有虚拟主机的概念,默认提供了一个defaultVhost的虚拟主机在配置文件里,虚拟主机内有单独的关于主机的配置,hls代表开启hls的视频协议功能,http_remux,是否为http开启直播流服务,mout代表的是挂载的http流,可以是不同的格式,默认是flv,可选有ts,即后缀是.ts,有mp3,aac等协议。rtc代表是否给虚拟主机开启webrtc的功能,并且是否开启rtmp转rtc,以及rtc转rtmp的功能。http_hooks是SRS在有客户端推流或者拉流的时候配置的一个接口回调,这个回调可以是我们自己写的后端服务,这里的配置是我配置的我实际的后端服务的接口地址,可以根据自己的实际情况进行调整,enable代表是开启HOOK,publish是推流的回调,unpublish是停止推流的时候,play和stop是拉流的播放和停止回调。play是针对拉流的配置,gop_cache是否缓存最后一帧,如果开启,客户端能够快速播放,如果关闭,客户端拉取的一直都是最新的,queue_length是缓存的帧一秒缓存的队列长度,如果超过这个,会移除之前的帧,mw_latency,关于流的合并写入的延迟,毫秒级单位。Publish是推流的一个配置,mr是合并读取的延迟,毫米级单位。

    关于上面说了那么多的配置,主要的配置还是http_hooks的配置,这个配置,是SRS在接收到推流请求,或者停止推流,以及拉流,停止拉流的时候对我们后端服务的一个回调,enabled代表是否开启回调,publish是开始推流的回调,unpublish是停止推流,play和stop是客户端在播放流或者停止流的时候的一个回调,这里如果部署在外网,且srs和后端服务在一个服务器,此处的地址可以使用局域网的地址,与前端配置不同的是,前端的配置必须是外网的地址。

 

    以上关于所有的全面配置可以参考以下网址:

    http_api:http://ossrs.net/lts/zh-cn/docs/v6/doc/http-api

    http_server:http://ossrs.net/lts/zh-cn/docs/v6/doc/http-server

    rtc_server/rtc:http://ossrs.net/lts/zh-cn/docs/v6/doc/webrtc

    hls:http://ossrs.net/lts/zh-cn/docs/v6/doc/hls

 

 

部署

    上面说到,我们的发布环境是centos,nginx和docker,所以在安装好了nginx之后 需要对nginx进行一个端口反向代理的配置,这里我用的是443端口,在网上生成了一个ssl证书,因为如果是使用http开头的网址,浏览器的机制,会不让使用摄像头,需要更改浏览器的配置才可以使得http的网址可以访问摄像头,如果是在本地部署和调试此服务,建议使用127.0.0.1或者localhost等方式来获取摄像头的信息,因为浏览器的安全机制,非https并且url地址是IP非127.0.0.1或者localhost的方式获取摄像头是有限制,接触限制的方式是在浏览器地址输入chrome://flags,回车之后,在弹出的页面中搜索Insecure origins treated as secure,如图,回车之后,需要将服务的IP地址输入在下方输入框中,并且将disabled更改为enabled,在更改完成后,浏览器下方会出现图3的面板,点击Relauch重启浏览器即可通过IP地址访问服务,并且加载摄像头,如果是中文disable是禁用,enable是启用,Relauch是重启。

    所以基于上面http的问题,需要生成一个ssl证书,让web使用https进行访问。下面我放一份我的nginx的配置,在下面的443的配置中,指定了servicename,以及root指向的是我们发布的之后的web前端的地址。指定了index.html,以及ssl证书相关的配置地址,配置根路径访问的是web前端的index.html,然后将路由中包括api,pull,push的指向对应的端口,如上图的端口配置情况,1985,使用webrtc进行推流,8080,进行拉流的端口,video是signalr的反向代理地址。

    以上是我服务器自己部署的nginx的一个配置。

 

    

  

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /video/dist/;
        index index.html;
        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
        location / {
            try_files $uri $uri/ /index.html;
        }
        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
    server {
        listen      443 ssl;
        listen       [::]:443;
        server_name  49.233.22.57;
        root         /video/dist/;
        index index.html;
        ssl_certificate /sslfile/49.233.22.57.crt; # ssl证书存储路径
        ssl_certificate_key /sslfile/49.233.22.57.private; # 秘钥存储路径

        # ssl的一些配置
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_prefer_server_ciphers  on;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #开启TLS协议

        location / {
            try_files $uri $uri/ /index.html;
        }
        location /api {
            proxy_pass http://10.2.20.12:5000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
        }
        location /rtc {
            proxy_pass http://10.2.20.12:1985;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
        }
        location /pull {
            rewrite ^/pull/(.*)$ /$1 break;
            proxy_pass http://10.2.20.12:8080;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
        }
        location /video {
            proxy_pass http://10.2.20.12:5000;
            proxy_set_header Host $host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_cache_bypass $http_upgrade != '';
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
        }
	}

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2;
#        listen       [::]:443 ssl http2;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

}

    后端部署在docker中, 环境是net8的开发环境,dockerfile配置如下,将发布后的文件和dockerfile放在一起,执行docker build -t videoimg .指令,打包docker镜像。记得后面有一个点.,回车之后,生成了videoimg的docker镜像,生成镜像后,需要启动容器,docker run --name videoc --security-opt seccomp=unconfined  -d -p 5000:8080 videoimg 回车之后即可启动了后端服务的容器,本机的端口是5000,需要防火墙或者云服务器开启5000端口,

#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 8080
EXPOSE 8081
COPY . .

FROM base AS final
WORKDIR /app
ENTRYPOINT ["dotnet", "WebApplication1.dll"]

    docker启动SRS,如果SRS部署在外网服务器,需要在启动SRS容器之前,配置一个环境变量CANDIDATE="外网服务器IP地址",将外网的IP地址写入环境变量中,SRS启动会从中读取配置,也可以直接修改conf中关于CANDIDATE的配置直接更改为你的外网服务器的地址。配置好之后,启动SRS,docker run --rm  --name srs  -it -d -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 1990:1990 -p 8088:8088 -p 8000:8000/udp -v /video/conf:/conf --env CANDIDATE=$CANDIDATE     registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5 ./objs/srs -c /conf/console.conf  上面的指令,-v是将容器内部的conf文件夹挂载出来,然后在后面指定使用了console.conf作为启动的配置文件,并且将端口信息暴露出来,推拉流,以及web服务器需要使用这些端口。

    SRS提供了一个web管理系统,防火墙等配置好之后,在浏览器输入IP:8080即可打开如下页面,在控制台可以看到视频的推拉流信息,以及流量的流入和流出。

端口配置

    服务器需要开启一下端口

    1:后端服务的端口,例如本例子的5000端口

    2:SRS相关端口:1935,1985,8080,1990,8088,8000/udp

代码和详细Windows文档地址

    关于更多的详细解读,可以查看写好的windows的文档部署地址,除了部署方式的差异,其余都一样。

    git地址:https://gitee.com/cxd199645/audio-video.git

总结

     关于做一个音视频通话的技术分享就到这里了,如果又不懂的,可以添加QQ/WX:934550201.

 

1. SRS

SRS是一个开源的(MIT协议)简单高效的实时视频服务器,支持RTMP、WebRTC、HLS、HTTP-FLV、SRT、MPEG-DASH和GB28181等协议。 SRS媒体服务器和FFmpegOBSVLC WebRTC等客户端配合使用,提供流的接收和分发的能力,是一个典型的发布 (推流)和订阅(播放)服务器模型。 SRS支持互联网广泛应用的音视频协议转换,比如可以将RTMPSRT 转成HLSHTTP-FLVWebRTC等协议。

From:https://www.cnblogs.com/1996-Chinese-Chen/p/18384394
本文地址: http://www.shuzixingkong.net/article/1519
0评论
提交 加载更多评论
其他文章 B 端产品未来几年的发展趋势
未来几年,B 端产品领域将面临着诸多挑战和机遇。人工智能与机器学习的深度融合、云计算与容器化技术的持续发展、用户体验与设计的重要性日益凸显、数据安全与隐私保护的挑战与机遇、行业垂直化与专业化发展以及敏捷开发与持续交付的普及等趋势,将对 B 端产品经理提出更高的要求
B 端产品未来几年的发展趋势 B 端产品未来几年的发展趋势 B 端产品未来几年的发展趋势
Python中的分布式框架Ray的安装与使用
本文介绍了基于Python的分布式框架Ray的基本安装与使用。Ray框架下不仅可以通过conda和Python十分方便的构建一个集群,还可以自动的对分布式任务进行并发处理,且支持GPU分布式任务的提交,极大的简化了手动分布式开发的工作量。
Python中的分布式框架Ray的安装与使用 Python中的分布式框架Ray的安装与使用 Python中的分布式框架Ray的安装与使用
【VMware VCF】VCF 5.2:挂载远程 vSAN 数据存储。
VMware vSAN 解决方案中,为了充分利用 vSAN HCI 集群内的存储资源, vSAN HCI 和 vSAN HCI 集群之间可以相互共享存储资源,这种解决方案早期叫 vSAN HCI Mesh,现在被称为具有数据存储共享的 vSAN HCI(vSAN HCI with datastore
【VMware VCF】VCF 5.2:挂载远程 vSAN 数据存储。 【VMware VCF】VCF 5.2:挂载远程 vSAN 数据存储。 【VMware VCF】VCF 5.2:挂载远程 vSAN 数据存储。
微信小程序 BLE 基础业务接口封装
写在前面:本文所述未必符合当前最新情形(包括蓝牙技术发展、微信小程序接口迭代等)。 微信小程序为蓝牙操作提供了很多接口,但在实际开发过程中,会发现隐藏了不少坑。目前主流蓝牙应用都是基于低功耗蓝牙(BLE)的,本文介绍相关的几个基础接口,并对其进行封装,便于业务层调用。 蓝牙发展 在开发蓝牙应用程序之
最全!嵌入式STM32单片机开发环境配置教学Win/Mac!!!
嵌入式STM32单片机开发环境配置教学Win/Mac · 本教程支持Windows和Mac · Windows可选的开发软件为Keil、Clion、STM32CubeMX,可自由选择开发方式 · Mac的开发环境为(Clion+OpenOCD+STM32CubeMX),
最全!嵌入式STM32单片机开发环境配置教学Win/Mac!!! 最全!嵌入式STM32单片机开发环境配置教学Win/Mac!!! 最全!嵌入式STM32单片机开发环境配置教学Win/Mac!!!
WPF 如何利用Blend给Button添加波纹效果
先看一下效果吧: 如果不会写动画或者懒得写动画,就直接交给Blend来做吧; 其实Blend操作起来很简单,有点类似于在操作PS,我们只需要设置关键帧,鼠标点来点去就可以了,Blend会自动帮我们生成我们想要的动画效果. 第一步:要创建一个空的WPF项目 第二步:右键我们的项目,在最下方有一个,在B
WPF   如何利用Blend给Button添加波纹效果 WPF   如何利用Blend给Button添加波纹效果 WPF   如何利用Blend给Button添加波纹效果
关于告警,要想做好,从这些方面着手
各类监控系统都会产生告警事件,于是,就产生了 FlashDuty、PagerDuty、Opsgenie 这类产品,做告警事件的收敛降噪、排班认领升级等。如果你想增强自己公司的告警事件处理能力,参考(chao xi)这些产品的功能就可以了 😎。 告警集成:目标是在一个Oncall平台上
关于告警,要想做好,从这些方面着手
深度解析HarmonyOS SDK实况窗服务源码,Get不同场景下的多种模板
HarmonyOS SDK实况窗服务(Live View Kit)作为一个实时呈现应用服务信息变化的小窗口,遍布于设备的各个使用界面,它的魅力在于将复杂的应用场景信息简洁提炼并实时刷新,在不影响当前其他应用操作的情况下,时刻向用户展示最新的信息动态,用户也可以点击实况窗卡片或胶囊进入应用落地页查看详
深度解析HarmonyOS SDK实况窗服务源码,Get不同场景下的多种模板 深度解析HarmonyOS SDK实况窗服务源码,Get不同场景下的多种模板 深度解析HarmonyOS SDK实况窗服务源码,Get不同场景下的多种模板