Gradio全解11——Streaming:流式传输的视频应用(2)——Twilio:网络服务提供商

    • 11.2 Twilio:网络服务提供商
      • 11.2.1 Twillo穿透服务与TURN服务器
        • 1. 什么是STUN、TURN和ICE?
        • 2. Twilio介绍及网络穿透服务
        • 3. Twilio计费原理
      • 11.2.2 通过Twilio建立连接
        • 1. 安装Twilio并测试两类Client
        • 2. 使用Stream建立Twilio连接
      • 11.2.3 电话集成:使用Twilio拨打外呼电话
        • 1. handler注意事项
        • 2. 设置专属电话号码指向FastAPI URL
        • 3. 示例:使用Twilio外呼电话代码

本章目录如下:

  1. 《Gradio全解11——Streaming:流式传输的视频应用(1)——FastRTC:Python实时通信库》
  2. 《Gradio全解11——Streaming:流式传输的视频应用(2)——Twilio:网络服务提供商》
  3. 《Gradio全解11——Streaming:流式传输的视频应用(3)——YOLO系列模型技术架构与实战》
  4. 《Gradio全解11——Streaming:流式传输的视频应用(4)——基于Gradio.WebRTC+YOLO的实时目标检测》
  5. 《Gradio全解11——Streaming:流式传输的视频应用(5)——RT-DETR:实时端到端检测模型》
  6. 《Gradio全解10——Streaming:流式传输的视频应用(6)——基于RT-DETR模型构建目标检测系统》
  7. 《Gradio全解11——Streaming:流式传输的视频应用(7)——多模态Gemini模型及其思考模式》
  8. 《Gradio全解11——Streaming:流式传输的视频应用(8)——Gemini Live API:实时音视频连接》
  9. 《Gradio全解11——Streaming:流式传输的视频应用(9)——使用FastRTC+Gemini创建沉浸式音频+视频的艺术评论家》

11.2 Twilio:网络服务提供商

本节先讲解Twillo与TURN服务器概念,然后进行Twilio网络穿透服务实战,包括通过Twilio建立连接和使用Twilio拨打外呼电话。

11.2.1 Twillo穿透服务与TURN服务器

如果我们想在任意云提供商部署Gradio应用程序,则需要使用Twilio的API来获取他们的TURN服务器。那什么是TURN服务器,Twilio如何计费呢?

1. 什么是STUN、TURN和ICE?

STUN、TURN和ICE是IETF(The Internet Engineering Task Force:国际互联网工程任务组)制定的标准协议组,用于在建立点对点通信会话时穿透NAT(Network Address Translation,网络地址转换)。STUN、TURN和ICE的功能如下所述:

  • 当主机位于NAT防火墙后方时,可通过NAT会话穿透工具STUN( Session Traversal Utilities for NAT)发现主机的公网IP地址;若该主机需接收对端连接,会将主机公网IP地址作为可连接地址提供。若NAT防火墙仍阻止主机直连,双方则连接至NAT中继穿透服务器TURN(Traversal Using Relay around NAT),通过该服务器中转媒体流。
  • WebRTC及其他VoIP技术栈通过支持交互式连接建立协议ICE(Interactive Connectivity Establishment )来提升IP通信的可靠性,ICE是协调STUN与TURN以实现主机间连接的综合性标准。

关于STUN、TURN和ICE具体如何工作,请参考:How do STUN, TURN and ICE work?🖇️链接11-16。

2. Twilio介绍及网络穿透服务

Twilio是一家提供云通信平台即服务(CPaaS)的美国公司,其产品允许开发者通过API集成短信、语音通话、视频、电子邮件、发送WhatsApp消息和身份验证等功能到应用程序中。Twilio提供的服务包括以下几类:

  • Twilio基础组件: Programmable SMS、Programmable Voice、2FA with Verify、Twilio API、Webhooks等。
  • 开发者工具:Code Exchange、OpenAPI、Functions and Assets、Marketplace、Studio、TwiML Bins、Twilio CLI等。
  • 开发资源:API status、Changelog、Error and Warning Dictionary、Glossary等。
  • Twilio产品类:Twilio Content Template Builder、Conversational Intelligence、Elastic SIP Trunking、Flex、Event Streams、Network Traversal Service等。

除了网络穿透服务,其它内容已超出本书范围,感兴趣读者请参阅官网文档:🖇️链接11-17。Twilio的网络穿透服务(Network Traversal Service)是一项全球分布式STUN/TURN服务,它兼容ICE的客户端(如支持WebRTC标准的浏览器),可帮助厂商部署更可靠的P2P通信应用。在WebRTC和VoIP应用中可使用该服务实现NAT/防火墙穿透和中继,确保用户每次都能成功建立连接。更多信息请参考:Network Traversal Service🖇️链接11-18。

3. Twilio计费原理

Twilio的计费基于TURN服务器中转的数据量,TURN Client负责在TURN服务器上分配中继地址(也称为TURN会话)。中转数据总量按TURN Client发送和接收的字节数总和计算,系统随后会向创建该会话的TURN Client关联的Twilio Account SID收取费用。计费以兆字节为单位中转数据总量为依据,请注意不同Twilio区域的资费标准有所不同,登录Twilio Console(🖇️链接11-19)可查看发送记录、账单等。

11.2.2 通过Twilio建立连接

Twilio网络穿透服务实战包括两部分:使用Twilio建立连接并发送消息,以及使用Twilio拨打外呼电话,先讲述第一部分。本节内容包括安装Twilio并测试,然后使用Stream建立Twilio连接。

1. 安装Twilio并测试两类Client

从Python包管理工具PiPy安装Twilio,命令如下:

pip3 install twilio

测试安装,尝试给自己发送一条短信。更新以下代码示例中的account_sid、auth_token和from_,其中from_使用用户Twilio账户中的电话号码,to应为个人手机号码。代码如下所示:

from twilio.rest import Client
# Your Account SID and Auth Token from console.twilio.com
account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
auth_token  = "your_auth_token"
client = Client(account_sid, auth_token)
message = client.messages.create(to="+8615558675309",from_="+8615017250604", body="Hello from Python!")
print(message.sid)

运行代码并稍等片刻后,将在手机上收到短信。

也可以使用api_key和api_secret代替auth_token进行认证,并将发送短信改为拨打电话,代码如下所示:

from twilio.rest import Client
api_key = "XXXXXXXXXXXXXXXXX"
api_secret = "YYYYYYYYYYYYYYYYYY"
account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
client = Client(api_key, api_secret, account_sid)
call = client.calls.create(to="9991231234", from_="9991231234",url="http://twimlets.com/holdmusic?Bucket=com.twilio.music.ambient")
print(call.sid)

关于url的设置请参考11.3.3节。关于twilio-python库更多信息请参考:🖇️链接11-20。

2. 使用Stream建立Twilio连接

如需在WebRTC应用中使用Twilio网络穿透服务,只需获取令牌并传入Stream的构造函数。请按以下步骤操作:

  • 首先,从Web服务器发起请求以获取网络穿透服务令牌,然后将其传递至WebRTC应用。获取网络穿透服务令牌需使用Twilio账户的SID和认证token,为保障Twilio账户凭证安全,请务必通过服务器而非客户端浏览器发起该请求。
import os
from twilio.rest import Client
# Find your Account SID and Auth Token at twilio.com/console
# and set the environment variables. See http://twil.io/secure
account_sid = os.environ["TWILIO_ACCOUNT_SID"]
auth_token = os.environ["TWILIO_AUTH_TOKEN"]
client = Client(account_sid, auth_token)
token = client.tokens.create()
print(token)

打印结果与如下所示内容类似:

{"username": "dc2d2894d5a9023620c467b0e71cfa6a35457e6679785ed6ae9856fe5bdfa269","ice_servers": [{"urls": "stun:global.stun.twilio.com:3478"},{"username": "dc2d2894d5a9023620c467b0e71cfa6a35457e6679785ed6ae9856fe5bdfa269","credential": "tE2DajzSJwnsSbc123","urls": "turn:global.turn.twilio.com:3478?transport=udp"},{"username": "dc2d2894d5a9023620c467b0e71cfa6a35457e6679785ed6ae9856fe5bdfa269","credential": "tE2DajzSJwnsSbc123","urls": "turn:global.turn.twilio.com:3478?transport=tcp"},{"username": "dc2d2894d5a9023620c467b0e71cfa6a35457e6679785ed6ae9856fe5bdfa269","credential": "tE2DajzSJwnsSbc123","urls": "turn:global.turn.twilio.com:443?transport=tcp"}],"date_updated": "Fri, 01 May 2020 01:42:57 +0000","account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX","ttl": "86400","date_created": "Fri, 01 May 2020 01:42:57 +0000","password": "tE2DajzSJwnsSbc123"
}
  • 接下来,构造RTC配置。在建立呼叫时,将包含iceServers属性的RTCConfiguration对象传入Stream构造函数的属性rtc_configuration中,如下所示:
rtc_configuration = {"iceServers": token.ice_servers,"iceTransportPolicy": "relay"}
stream = Stream(handler=detection, modality="video",mode="send-receive", ..., rtc_configuration=rtc_configuration)

从此节点开始,已使用网络穿透服务建立连接,用户可以像往常一样交换SDP(Session Description Protocol,会话描述协议)的offer/answer。

11.2.3 电话集成:使用Twilio拨打外呼电话

电话集成用例主要为了演示FastRTC的Stream如何结合Twilio,实现发起呼叫、接听语音助手和流式传输音频功能。内容包括电话集成注意事项,设置集成流程并配置Twilio电话号码,以及使用Twilio外呼电话代码。

1. handler注意事项

使用电话集成时,Stream的处理函数handler应注意事项包括:

  • 不要求任何额外输入:要使Stream的handler能通过电话正常工作,必须确保handler除了音频数据外,不要求任何额外输入。若调用await self.wait_for_args(),Stream将永久等待额外输入数据。StreamHandler具有phone_mode属性,当运行在电话模式时该属性值为True,我们可利用此属性判断是否需要等待额外输入数据。
  • ReplyOnPause与电话集成:传递给ReplyOnPause的生成器函数必须为除audio外的所有参数设置默认值。若生成AdditionalOutputs,这些输出将在下次调用生成器时,作为输入参数传递给生成器。请参阅11.2.1节提到的示例Talk To Claude,了解作为handler的ReplyOnPause如何兼容电话使用;同时注意观察每次调用时,如何将输入的聊天历史记录生成为AdditionalOutput。
2. 设置专属电话号码指向FastAPI URL

在电话集成示例中,我们可以将Twilio等SIP提供商与Stream集成,并为应用程序设置专属电话号码。设置流程如下:

  1. 创建Twilio账户:注册Twilio账户并购买支持语音功能的电话号码。对于试用账户,仅允许注册时使用的电话号码连接至Stream。
  2. 挂载Stream:通过方法stream.mount(app)将FastAPI应用挂载至Stream,并启动服务器,得到应用URL。示例代码如下:
from fastrtc import Stream, ReplyOnPause
from fastapi import FastAPI
def echo(audio):yield audio
app = FastAPI()
stream = Stream(ReplyOnPause(echo), modality="audio", mode="send-receive")
stream.mount(app)
# run with `uvicorn main:app`
  1. 配置Twilio Webhook:将您购买的Twilio电话号码指向第二步生成的网络钩子URL。

第三步配置Twilio电话号码详细步骤如下:

  1. 进入Twilio账户控制台左侧导航栏,然后依次单击Develop→Manage→TwiML apps→Create new TwiML App。如图11-1所示:
    在这里插入图片描述

    图11-1

  2. 为TwiML应用命名后(如FastRTCPhone),将Voice Configuration中实现语音功能的Request URL设置为FastAPI应用地址,并在末尾添加/telephone/incoming,例如:https://your-app-url.com/telephone/incoming。最后保存即可,界面如图11-2所示:
    在这里插入图片描述

    图11-2

技术拓展:在本地开发时,可通过Ngrok(🖇️链接11-21)将本地服务器暴露至公网。操作步骤:先启动ngrok服务:

ngrok http <port>

然后将Twilio Voice URL设置为:https://your-ngrok-subdomain.ngrok.io/telephone/incoming-call

3. 示例:使用Twilio外呼电话代码

本节演示如何通过twilio-python模块实现电话呼叫,包括发起呼叫、接听语音助手和流式传输音频功能,代码如下所示:

from twilio.rest import Client
import gradio as gr
from fastrtc import Stream, ReplyOnPause
from fastapi import FastAPI
def echo(audio):yield audio
app = FastAPI()
stream = Stream(ReplyOnPause(echo), modality="audio", mode="send-receive")@app.post("/call")
async def start_call(req: Request):body = await req.json()from_no = body.get("from")to_no = body.get("to")account_sid = os.getenv("TWILIO_ACCOUNT_SID")auth_token = os.getenv("TWILIO_AUTH_TOKEN")client = Client(account_sid, auth_token)# Use the public URL of your application# here we're using ngrok to expose an app running locallycall = client.calls.create(to=to_no, from_=from_no,url="https://[your_ngrok_subdomain].ngrok.app/incoming-call")return {"sid": f"{call.sid}"}@app.api_route("/incoming-call", methods=["GET", "POST"])
async def handle_incoming_call(request: Request):from twilio.twiml.voice_response import VoiceResponse, Connectresponse = VoiceResponse()response.say("Connecting to AI assistant"connect = Connect()path = request.url.path.removesuffix("/telephone/incoming")connect.stream(url=f"wss://{request.url.hostname}{path}/telephone/handler")response.append(connect)response.say("The call has been disconnected.")return HTMLResponse(content=str(response), media_type="application/xml")@app.websocket("/media-stream")
async def handle_media_stream(websocket: WebSocket):# stream is a FastRTC stream defined elsewhereawait stream.telephone_handler(websocket)
app = gr.mount_gradio_app(app, stream.ui, path="/")
stream.ui.launch()

代码中函数结合Twilio,依次实现呼叫、接听语音助手和流式传输音频功能,最后将FastAPI挂载到Gradio界面并启动。其中流式传输音频是基于WebSocket实现的,而不是WebRTC。各个函数解析如下:

  • start_call:启动呼叫。从请求Request中获取呼叫和被呼叫号码,然后创建客户端并开始呼叫。
  • handle_incoming_call:处理来电,例如通过Twilio(取决于电话设置)。它生成TwiML指令,将来电连接至WebSocket处理程序(如/telephone/handler)以进行音频流传输。参数request是用于处理来电webhook的FastAPI Request对象,返回包含TwiML指令(XML格式)的HTMLResponse。
  • stream.telephone_handler:电话处理程序,它接受传入的WebSocket连接对象,是通过Twilio电话进行流式传输音频的WebSocket连接处理端点。

更多信息请参考:Telephone Integration🖇️链接11-22。

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

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

相关文章

【更新至2024年】2009-2024年各地级市金融科技水平数据

【更新至2024年】2009-2024年各地级市金融科技水平数据 1、时间&#xff1a;2009-2024年 2、来源&#xff1a;天眼查 3、指标&#xff1a;年份、省份、地级市、地级市代码、当年新注册金融科技公司数量、累计注册金融科技公司数量、金融科技水平 4、范围&#xff1a;地级市…

一般软件加载显示图片的流程

目录 1、一般图片浏览软件的流程&#xff08;Qt 或类似框架&#xff09;&#xff1a; 1️⃣ 读取原始数据 2️⃣ 解析图片格式 3️⃣ 存储到内部可用的绘制对象 4️⃣ 显示到界面 ✅ 总结 2、那什么叫“QPixmap 在 Qt 里就是“显示专用的像素缓存”&#xff0c;不是原始…

【论文阅读】REFRAG:一个提升RAG解码效率的新思路

引言 看到一则报道[1]&#xff0c;重组后的Meta实验室在9月1号发布了一篇关于提升RAG解码效率的论文&#xff0c;提出的思路有点启发作用&#xff0c;于是把原文下载下来仔细看下。 论文标题&#xff1a;REFRAG: Rethinking RAG based Decoding 论文地址&#xff1a;https://ar…

QT M/V架构开发实战:QFileSystemModel介绍

目录[TOC](目录)前言一、QFileSystemModel初步介绍二、基本功能1.创建2.基本属性与方法三、示例&#xff08;简单的文件浏览器&#xff09;四、性能注意事项前言 本文主要介绍的是使用代码生成的情况下对控件的介绍&#xff0c;包括拥有的功能及能修改的样式&#xff0c;也会说…

视频生成迎来效率革命!字节提出视频生成稀疏注意力机制,计算量降20倍,速度升17.79倍!

论文链接&#xff1a;https://arxiv.org/pdf/2509.01085亮点直击BSA——一种可训练的双向动态稀疏注意力框架&#xff0c;该框架首次在视频扩散训练中对全注意力机制中的查询&#xff08;Query&#xff09;及键值对&#xff08;Key-Value&#xff09;进行正交稀疏化处理以加速训…

STM32HAL库_cubeMX

ADC简介STM32f103的是12位逼近型ADC代码连续非扫描模式&#xff08;1个通道&#xff09;1&#xff1a;校准ADC&#xff08;这个可要可不要&#xff09;2&#xff1a;ADC初始化3&#xff1a;配置ADC通道&#xff08;这个函数只有一个通道时就是可要可不要&#xff09;4&#xff…

【Qt】清空QDateTimeEdit

代码 ui->startDate->setSpecialValueText(" "); //这里是空格 ui->startDate->setMinimumDate(QDate(2024, 1, 1)); ui->startDate->setDate(QDate::fromString("2024-01-01", "yyyy-MM-dd"));原理 设置特殊值显示文本&#…

LiTS 2017 datasets

下载记录 论文地址&#xff1a;https://doi.org/10.1016/j.media.2022.102680 官方下载链接&#xff1a;https://competitions.codalab.org/competitions/17094 进入链接后&#xff0c;需要先注册才能拿到下载点击Train data下面的Mirro1&#xff0c;在google云盘会看到Trai…

kafka3.8集群搭建

kafka集群需要三台机器搭建&#xff0c;并使用内置zookeeperIP10.0.0.110.0.0.210.0.0.3安装jdk # ubuntu sudo apt install -y openjdk-8-jdk-headless # centos sudo yum install -y java-1.8.0-openjdk下载kafka wget https://archive.apache.org/dist/kafka/3.8.1/kafka_2…

从15kHz 到20MHz:为什么LTE带宽不能被子载波间隔整除?

从 15 kHz 到 20 MHz&#xff1a;为什么 LTE 带宽不能被子载波间隔整除&#xff1f; 1. 引言 在 LTE 系统中&#xff0c;子载波间隔被固定为 15 kHz&#xff0c;而系统带宽却被设计为 1.4、3、5、10、15、20 MHz 六个档位。乍一看&#xff0c;这些带宽似乎无法被 15 kHz 整除&a…

html css js网页制作成品——HTML+CSS娃娃店网页设计(4页)附源码

目录 一、👨‍🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML

【计算机网络 | 第15篇】动态主机配置协议

文章目录为何需要DHCP&#xff1f;手动配置的痛点&#x1f914;DHCP的基本工作模式&#x1f95d;DHCP的核心功能&#xff1a;IP地址的动态管理&#x1f95d;租用期的特点租用期的管理机制DHCP四步工作流程&#xff1a;从“发现”到“绑定”&#x1f426;‍&#x1f525;中继代理…

嵌入式系统内存分段核心内容详解

一、嵌入式内存分段整体规则&#xff08;按地址从低到高&#xff09;嵌入式系统内存按 “功能 属性” 划分为 6 个核心段&#xff0c;地址从低到高依次分布&#xff0c;各段职责与存储对象明确&#xff0c;具体规则如下表&#xff1a;地址范围段类型&#xff08;Segment&#…

开发避坑指南(45):Java Stream 求两个List的元素交集

需求 java 中如何用stream求两个List元素的交集&#xff1f; 代码实现 直接上代码 public class ListTest {public static void main(String[] args) {List<Integer> list1 new ArrayList<>();list1.add(1);list1.add(2);list1.add(3);List<Integer> list2 …

gitlab流水线与k8s集群的联通

gitlab流水线与k8s集群的连接&#xff0c;首先是通过gitlab-ci.yml文件中的命令&#xff0c;通过runner执行器实例运行对应的kubectl命令实现的。 那么runner执行器实例执行器如何执行kubectl命令&#xff0c;执行环境的配置&#xff0c;kubectl命令如何与k8s集群互认&#xff…

【Linux】常用命令速查表

Linux 常用命令速查表查看进程内存映射pmap -x <pid> # 查看进程的内存映射信息查看系统架构uname -m # 查看操作系统架构&#xff08;x86_64 / arm64 等&#xff09;磁盘与文件du -sh /home/* # 查看 /home 下每个用户目录的大小&#x…

Windows下编译SLEPc

本文记录在Windows下编译SLEPc的流程。 零、环境 操作系统Windows 11VS Code1.92.1MSYS2msys2-x86_64-20250830 一、安装依赖 1.1、依赖 首先&#xff0c;下载并安装MSYS2&#xff0c; 打开MSYS2 MINGW64控制台&#xff0c;运行以下命令安装依赖包&#xff0c; pacman -S …

运动生理实验室解决方案 人体生理实验整体解决方案

&#xff08;一&#xff09;、硬件参数 集成化折叠式无创型生理实验平台&#xff1a;1.1、 集成化设计:至少包含设备操作台、可收纳式交互实验桌、可收纳式检查床、生物信号 采集处理系统、计算机工作站集成于一体的高度集成设计&#xff1b;&#xff08;o561-6o623…

Axure RP 9 最新版安装包+安装步骤Win系统适用(附安装包)

Axure RP 9​ 是一款专业的 ​原型设计工具&#xff0c;主要用于 ​网站、APP、软件等产品的界面设计和交互原型制作。 一、准备工作 ​下载好安装包​ Axure RP 9安装包下载&#xff1a;https://pan.quark.cn/s/bc2b35011106 二、开始安装 第一步&#xff1a;双击运行安装包…

AutoMQ 亮相首尔:KafkaKRU 分享日志流处理新思路

全球 Kafka 社区都在关注 AutoMQ&#xff01;凭借在 Kafka 生态的独特创新&#xff0c;AutoMQ 深受 Kafka 用户喜爱&#xff0c;已成为众多企业和开发者的首选实时数据解决方案。昨天&#xff0c;我们非常高兴看到来自韩国的 KafkaKRU 核心社区在首尔举办第2届官方线下交流会。…