新增页面
This commit is contained in:
parent
95bbabf00a
commit
2919bdfc90
9
.hbuilderx/launch.json
Normal file
9
.hbuilderx/launch.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"version" : "1.0",
|
||||
"configurations" : [
|
||||
{
|
||||
"playground" : "standard",
|
||||
"type" : "uni-app:app-ios"
|
||||
}
|
||||
]
|
||||
}
|
435
common/Order/OrderAll.vue
Normal file
435
common/Order/OrderAll.vue
Normal file
@ -0,0 +1,435 @@
|
||||
<template>
|
||||
<view class="flexTop">
|
||||
<view class="content">
|
||||
<view v-for="(item,index) in goodList" :key="index">
|
||||
<view class="box">
|
||||
<view class="flex">
|
||||
<text class="text1">订单编号:{{item.id}}</text>
|
||||
<text
|
||||
class="text2">{{item.status=='SUBMITTED'?'等待付款':item.status=='PAID'?'等待发货':item.status=='DELIVERED'?'等待收货':item.status=='FINISHED'?'交易成功':item.status=='CANCELED'||item.status=='CLOSED'?'交易关闭':item.status=='WAITING_FOR_REFUND'?'审核中':item.status=='REFUNDING'?'退款处理中':item.status=='REFUND_REJECTED'?'驳回':item.status=='REFUND_FINISHED'?'退款完成':''}}</text>
|
||||
</view>
|
||||
<view class="flex-column" v-for="(item1,index1) in item.items" :key="index1"
|
||||
@click="gotoStatu(item)">
|
||||
<view>
|
||||
<image :src="item1.colorPic" class="img"></image>
|
||||
</view>
|
||||
<view class="flex-d1">
|
||||
<view class="flex-w">
|
||||
<text class="text1">{{item1.silkName}}</text>
|
||||
<text class="text2">x{{item1.length}}米</text>
|
||||
</view>
|
||||
<text class="text3">{{item1.pricePreMeter}}元/米</text>
|
||||
<text class="text3">¥{{item1.price}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex1">
|
||||
<text class="text1">{{status==1?'应付金额:':'实付金额:'}}¥{{item.actual}}</text>
|
||||
<view class="view1">
|
||||
<view style="margin: 0 5rpx;"
|
||||
v-if="item.status=='PAID'||item.status=='DELIVERED'||item.status=='FINISHED'">
|
||||
<up-button size="small" :plain="true" :hairline="true"
|
||||
@click="afterSale(item)" color="#909399">售后</up-button>
|
||||
</view>
|
||||
<view style="margin: 0 5rpx;" v-if="item.status=='PAID'||item.status=='DELIVERED'">
|
||||
<up-button size="small" :plain="true" :hairline="true"
|
||||
@click="receiveGoods(item)" color="#909399">确认收货</up-button>
|
||||
</view>
|
||||
<view style="margin: 0 5rpx;" v-if="item.status=='SUBMITTED'">
|
||||
<up-button size="small" :plain="true" :hairline="true"
|
||||
@click="cancelOrder(item)" color="#909399">取消订单</up-button>
|
||||
</view>
|
||||
<view style="margin: 0 5rpx;" v-if="item.status=='SUBMITTED'">
|
||||
<up-button type="error" size="small" :plain="true" :hairline="true"
|
||||
@click="gotoPuy(item)" color="#909399">立即付款</up-button>
|
||||
</view>
|
||||
<view style="margin: 0 5rpx;" v-if="item.status=='CANCELED'||item.status=='CLOSED'">
|
||||
<up-button size="small" :plain="true" :hairline="true"
|
||||
@click="delectOrder(item)" color="#f56c6c">删除订单</up-button>
|
||||
</view>
|
||||
<view style="margin: 0 5rpx;" v-if="item.status=='WAITING_FOR_REFUND'||item.status=='REFUNDING'||item.status=='REFUND_REJECTED'||item.status=='REFUND_FINISHED'">
|
||||
<up-button size="small" :plain="true" :hairline="true" @click="gotocustm()" color="#909399">联系客服</up-button>
|
||||
</view>
|
||||
<view style="margin: 0 5rpx;" v-if="item.status=='WAITING_FOR_REFUND'">
|
||||
<up-button size="small" type="error" :plain="true" :hairline="true" @click="cancelSale(item)" color="#909399">取消售后</up-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 申请售后弹窗 -->
|
||||
<view>
|
||||
<up-popup :show="popupShow" mode="bottom" :round="10" @close="popupShow=false" @open="open" closeable>
|
||||
<view class="cont">
|
||||
<view style="margin-top: 20rpx;text-align: center;font-size: 32rpx;">
|
||||
<text>选择面料</text>
|
||||
</view>
|
||||
<view class="flexpopup">
|
||||
<view class="content">
|
||||
<view v-for="(item,index) in afterSaleItem.items" :key="index">
|
||||
<view>
|
||||
<checkbox-group @change="handleChange(item)">
|
||||
<label class="flex-column">
|
||||
<view>
|
||||
<image :src="item.colorPic" class="img"></image>
|
||||
</view>
|
||||
<view class="flex-d">
|
||||
<view class="flex-w">
|
||||
<text class="text1">{{item.silkName}}</text>
|
||||
</view>
|
||||
<text class="text3">{{item.color}} {{item.length}}米</text>
|
||||
<text class="text3">实付价格:¥{{item.price}}</text>
|
||||
</view>
|
||||
<checkbox :checked="item.checked" />
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view style="margin-top: 30rpx;" @click="gotoAfterSale">
|
||||
<up-button shape="circle" color="linear-gradient(to right,#13b267,#258010)">下一步</up-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</up-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { deleteAction, getAction, postAction } from '../http';
|
||||
|
||||
const emit = defineEmits(['statueNow', 'cancelOrder', 'reset'])
|
||||
const status = ref(0)
|
||||
const popupShow = ref(false)
|
||||
const afterSaleItem = ref({})
|
||||
const goodList = ref([])//全部数据
|
||||
// const dataList=ref([])//展示
|
||||
onShow(() => {
|
||||
|
||||
})
|
||||
const cancelOrder = (item : any) => {
|
||||
emit('cancelOrder', item)
|
||||
}
|
||||
const gotoPuy = (item : any) => {
|
||||
postAction('/order/pay', { orderId: item.id }, { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }).then((res : any) => {
|
||||
if (res.code === 200) {
|
||||
let { nonceStr, prepayId, timeStamp, signature } = res.data
|
||||
prepayId = JSON.parse(prepayId).prepay_id
|
||||
let package1 = 'prepay_id=' + prepayId
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',// 支付类型微信支付wxpay/支付宝支付alipay
|
||||
orderInfo: {
|
||||
"appid": "wxc385500b1df207b8", // 微信开放平台 - 应用 - AppId,注意和微信小程序、公众号 AppId 可能不一致
|
||||
"noncestr": nonceStr, // 随机字符串
|
||||
"package": package1, // 固定值
|
||||
"partnerid": "1680435317", // 微信支付商户号
|
||||
"prepayid": prepayId, // 统一下单订单号
|
||||
"timestamp": timeStamp, // 时间戳(单位:秒)
|
||||
"sign": signature // 签名,这里用的 MD5/RSA 签名
|
||||
},
|
||||
timeStamp: timeStamp, // 时间戳(单位:秒)
|
||||
nonceStr: nonceStr, // 随机字符串
|
||||
package: package1, // 固定值
|
||||
signType: "RSA", // 签名,这里用的 MD5/RSA 签名
|
||||
paySign: signature,
|
||||
success: (res) => {
|
||||
console.log('支付成功', res)
|
||||
uni.showToast({
|
||||
title: '支付成功'
|
||||
})
|
||||
getAction('/order/getOrderById', { orderId: item.id }).then((res : any) => {
|
||||
if (res.code === 200) {
|
||||
uni.setStorageSync('orderGoods', JSON.stringify(res.data))
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/orderFlow/Order/orderDetails'
|
||||
})
|
||||
}, 100)
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}, 100)
|
||||
}
|
||||
})
|
||||
},
|
||||
fail: (result) => {
|
||||
uni.showToast({
|
||||
title: '支付失败',
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
const gotoStatu = (item : any) => {
|
||||
if(item.status=='WAITING_FOR_REFUND'||item.status=='REFUNDING'||item.status=='REFUND_REJECTED'||item.status=='REFUND_FINISHED'){
|
||||
uni.setStorageSync('orderGoods', JSON.stringify(item))
|
||||
uni.navigateTo({
|
||||
url: '/pages/orderFlow/afterSale/afterSale'
|
||||
})
|
||||
}else if (item.status == 'SUBMITTED') {
|
||||
uni.setStorageSync('orderGoods', JSON.stringify(item))
|
||||
uni.navigateTo({
|
||||
url: '/pages/orderFlow/Order/orderDetails?type=' + 1
|
||||
})
|
||||
} else {
|
||||
uni.setStorageSync('orderGoods', JSON.stringify(item))
|
||||
uni.navigateTo({
|
||||
url: '/pages/orderFlow/Order/orderDetails'
|
||||
})
|
||||
}
|
||||
}
|
||||
const changeStuta = (data : any, list : any) => {
|
||||
status.value = data
|
||||
setTimeout(() => {
|
||||
emit('statueNow', data)
|
||||
goodList.value = list
|
||||
}, 300)
|
||||
}
|
||||
defineExpose({
|
||||
changeStuta
|
||||
})
|
||||
const delectOrder = (item : any) => {
|
||||
uni.showModal({
|
||||
content: '是否删除该订单?',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
deleteAction(`/order/delete${item.id}`).then((res:any)=>{
|
||||
if(res.code===200){
|
||||
uni.showToast({
|
||||
icon:'success',
|
||||
title:'删除成功!'
|
||||
})
|
||||
goodList.value=goodList.value.filter(l=>l.id!=item.id)
|
||||
}else{
|
||||
uni.showToast({
|
||||
icon:'error',
|
||||
title:'删除失败!'
|
||||
})
|
||||
}
|
||||
})
|
||||
} else if (res.cancel) {
|
||||
console.log('用户点击取消');
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
const receiveGoods = (item : any) => {
|
||||
uni.showModal({
|
||||
content: '是否确认收货?',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
//拉起确认收货组件
|
||||
wx.openBusinessView({
|
||||
businessType: 'weappOrderConfirm',
|
||||
extraData: {
|
||||
merchant_id: '1680435317',
|
||||
merchant_trade_no: item.id,
|
||||
transaction_id: item.wechatPayBill
|
||||
},
|
||||
success() {
|
||||
postAction('/order/received', { orderId: item.id }, { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }).then((res : any) => {
|
||||
if (res.code === 200) {
|
||||
uni.showToast({
|
||||
title: '收货完成!',
|
||||
icon: 'success',
|
||||
})
|
||||
emit('reset', 1)
|
||||
}
|
||||
})
|
||||
},
|
||||
fail(err) {
|
||||
console.log(err);
|
||||
uni.showToast({
|
||||
title:'确认失败!',
|
||||
icon:'none',
|
||||
})
|
||||
},
|
||||
complete() {
|
||||
//dosomething
|
||||
}
|
||||
});
|
||||
} else if (res.cancel) {
|
||||
console.log('用户点击取消');
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
const afterSale = (item : any) => {
|
||||
item.items.forEach((l : any) => {
|
||||
l.checked = false
|
||||
})
|
||||
afterSaleItem.value = item
|
||||
popupShow.value = true
|
||||
}
|
||||
const open = () => {
|
||||
popupShow.value = true
|
||||
}
|
||||
const handleChange = (item : any) => {
|
||||
item.checked = !item.checked
|
||||
}
|
||||
const gotoAfterSale = () => {
|
||||
let arr = afterSaleItem.value.items.filter(l => l.checked);
|
||||
if (arr.length) {
|
||||
popupShow.value=false
|
||||
uni.navigateTo({
|
||||
url: '/pages/orderFlow/applicationRefund/applicationRefund?item=' + JSON.stringify(arr)+'&orderId='+ afterSaleItem.value.id
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '请选择退款订单!',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
const gotocustm=()=>{
|
||||
uni.reLaunch({
|
||||
url:'/pages/minPackage/customerService'
|
||||
})
|
||||
}
|
||||
const cancelSale=(item:any)=>{
|
||||
uni.showModal({
|
||||
content: '是否确认取消?',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
postAction('/refund/cancelByOrderId',{orderId:item.id}, { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }).then((res:any)=>{
|
||||
if(res.code===200){
|
||||
uni.showToast({
|
||||
title:'取消成功!',
|
||||
icon:'success'
|
||||
})
|
||||
emit('reset', 1)
|
||||
}
|
||||
})
|
||||
} else if (res.cancel) {
|
||||
console.log('用户点击取消');
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.flex1 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx;
|
||||
border-top: 1rpx solid #eeeeee;
|
||||
border-bottom: 1rpx solid #eeeeee;
|
||||
|
||||
.view1 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.text1 {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx;
|
||||
border-bottom: 1rpx solid #eeeeee;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.text1 {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.text2 {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
|
||||
.box {
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
|
||||
.flex-d {
|
||||
width: calc(100% - 280rpx);
|
||||
height: 170rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.text3 {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
.flex-d1 {
|
||||
width: calc(100% - 220rpx);
|
||||
height: 170rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.text3 {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.flex-w {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-left: 1%;
|
||||
|
||||
.text1 {
|
||||
font-size: 36rpx;
|
||||
padding: 2rpx 0;
|
||||
}
|
||||
|
||||
.text2 {
|
||||
font-size: 34rpx;
|
||||
color: #1abc9c;
|
||||
padding: 2rpx 0;
|
||||
}
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 190rpx;
|
||||
height: 190rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.flexTop {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 93vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.flexpopup {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 70vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.cont {
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
</style>
|
138
common/Order/addressTracking.vue
Normal file
138
common/Order/addressTracking.vue
Normal file
@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<view class="flex">
|
||||
<view class="flex-column">
|
||||
<image :src="textType[index].src" class="img"></image>
|
||||
<view class="line"></view>
|
||||
<view class="dot"></view>
|
||||
</view>
|
||||
<view style="width: 93%;">
|
||||
<view class="drc">
|
||||
<text class="text1">{{textType[index].tip}}</text>
|
||||
<text class="text2">{{textType[index].desc}}</text>
|
||||
</view>
|
||||
<view style="margin-top: 20rpx;">
|
||||
<view class="content">
|
||||
<view>{{radiolist[2]}}</view>
|
||||
<view style="color: #909399;">{{radiolist[0]}} {{radiolist[1]}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="querytot"></view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { ref } from 'vue'
|
||||
const radiolist = ref([])
|
||||
const lineHeight=ref('100rpx')//默认60rpx
|
||||
const index=ref(0)
|
||||
const textType=ref([
|
||||
{
|
||||
tip:'仓库处理中',
|
||||
desc:'仓库正在加急发货,请耐心等待',
|
||||
src:'../../static/0628仓库.png'
|
||||
},
|
||||
{
|
||||
tip:'快递已发货',
|
||||
desc:'快递已经发货,请耐心等待',
|
||||
src:'../../static/0628仓库.png'
|
||||
},
|
||||
{
|
||||
tip:'已完成',
|
||||
desc:'本次服务已完成,欢迎再次购买',
|
||||
src:'../../static/0628已完成.png'
|
||||
},
|
||||
{
|
||||
tip:'已取消',
|
||||
desc:'欢迎下次选购',
|
||||
src:'../../static/0628已取消.png'
|
||||
},
|
||||
{
|
||||
tip:'已关闭',
|
||||
desc:'本次服务已关闭,有疑问可以联系我们。欢迎再次购买',
|
||||
src:'../../static/0628已关闭.png'
|
||||
},
|
||||
])
|
||||
const goodList=ref()
|
||||
|
||||
onShow(()=>{
|
||||
goodList.value=JSON.parse(uni.getStorageSync('orderGoods'))
|
||||
radiolist.value=goodList.value.deliveryAddress.split("\n")
|
||||
|
||||
if(goodList.value.status=='PAID'){
|
||||
index.value=0
|
||||
}else if(goodList.value.status=='DELIVERED'){
|
||||
index.value=1
|
||||
}else if(goodList.value.status=='FINISHED'){
|
||||
index.value=2
|
||||
}else if(goodList.value.status=='CANCELED'){
|
||||
index.value=3
|
||||
}else if(goodList.value.status=='CLOSED'){
|
||||
index.value=4
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.querytot {
|
||||
background: url(../../static/bottomBorder.png) bottom repeat-x;
|
||||
background-size: 50%;
|
||||
padding: 10rpx 0 0;
|
||||
}
|
||||
.img{
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
padding-left: 5%;
|
||||
width: 7%;
|
||||
}
|
||||
|
||||
.dot {
|
||||
margin: 0 16rpx;
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
border-radius: 100%;
|
||||
background-color: #ffc4bc;
|
||||
}
|
||||
|
||||
.line {
|
||||
border-right: 1rpx solid #000000;
|
||||
width: 30rpx;
|
||||
margin: 10rpx 0;
|
||||
height: v-bind(lineHeight);
|
||||
}
|
||||
|
||||
.drc {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
padding: 10rpx 20rpx;
|
||||
|
||||
.text1 {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.text2 {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.img-icon {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
</style>
|
100
common/Order/commodity.vue
Normal file
100
common/Order/commodity.vue
Normal file
@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<view>
|
||||
<view v-for="(item,index) in goodList">
|
||||
<view class="flex-column">
|
||||
<view>
|
||||
<image :src="item.colorPic" class="img"></image>
|
||||
</view>
|
||||
<view class="flex-d">
|
||||
<view class="flex-w">
|
||||
<text class="text1">{{item.silkName}}</text>
|
||||
<text class="text2">{{item.length}}米</text>
|
||||
</view>
|
||||
<view class="flex-w">
|
||||
<text class="text3">{{item.color}}</text>
|
||||
<text
|
||||
class="text3">{{item.wrapType.indexOf('STRONG')>=0?'打卷(抗皱纸管)':item.wrapType.indexOf('COMMON')>=0?'打卷(普通纸管)':''}}</text>
|
||||
</view>
|
||||
<view class="flex-w">
|
||||
<text class="text4"> ¥{{item.pricePreMeter}}/米</text>
|
||||
<text class="text4">小计:¥{{item.price}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view style="display: flex;justify-content: flex-end;margin-right: 20rpx;"
|
||||
v-if="goodItem.status=='PAID'||goodItem.status=='DELIVERED'||goodItem.status=='FINISHED'">
|
||||
<view style="width: 25%;" @click="afterSale(item)">
|
||||
<up-button shape="circle">售后</up-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { ref } from 'vue'
|
||||
|
||||
const goodList = ref([])
|
||||
const goodItem = ref({})
|
||||
|
||||
onShow(() => {
|
||||
goodItem.value = JSON.parse(uni.getStorageSync('orderGoods'))
|
||||
goodList.value = JSON.parse(uni.getStorageSync('orderGoods')).items
|
||||
})
|
||||
|
||||
const afterSale=(item:any)=>{
|
||||
uni.navigateTo({
|
||||
url: '/pages/orderFlow/applicationRefund/applicationRefund?item=' + JSON.stringify([item])+'&orderId='+ goodItem.value.id
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.flex-column {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
|
||||
.flex-d {
|
||||
width: calc(100% - 220rpx);
|
||||
height: 170rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.text3 {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.flex-w {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-left: 1%;
|
||||
|
||||
.text1 {
|
||||
font-size: 36rpx;
|
||||
padding: 2rpx 0;
|
||||
}
|
||||
|
||||
.text2 {
|
||||
font-size: 34rpx;
|
||||
color: #1abc9c;
|
||||
padding: 2rpx 0;
|
||||
}
|
||||
|
||||
.text4 {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 190rpx;
|
||||
height: 190rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
</style>
|
79
common/Order/description.vue
Normal file
79
common/Order/description.vue
Normal file
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<view class="content">
|
||||
<view class="flex">
|
||||
<text>配送方式:</text>
|
||||
<text>{{goodList.expressType}}</text>
|
||||
</view>
|
||||
<view class="flex">
|
||||
<text>订单备注:</text>
|
||||
<text>{{goodList.comment?goodList.comment:'无'}}</text>
|
||||
</view>
|
||||
<view class="flex">
|
||||
<view style="display: flex;align-items: center;" @click="show=!show">
|
||||
<text>订单编号:</text>
|
||||
<up-icon name="arrow-down" color="#999999" size="20"></up-icon>
|
||||
</view>
|
||||
<text>{{goodList.id}}</text>
|
||||
</view>
|
||||
<view>
|
||||
<up-transition :show="show">
|
||||
<view class="flex">
|
||||
<text>缺货时处理方式:</text>
|
||||
<text>{{goodList.actionOnOOI}}</text>
|
||||
</view>
|
||||
<view class="flex">
|
||||
<text>蚕宝豆:</text>
|
||||
<text>获得{{goodList.getPoints}}蚕宝豆</text>
|
||||
</view>
|
||||
<!-- <view class="flex">
|
||||
<text>等级成长值:</text>
|
||||
<text>获得{{goodList.getExperience}}点积分</text>
|
||||
</view> -->
|
||||
<view class="flex">
|
||||
<text>微信转账单号:</text>
|
||||
<text>202406112456325461</text>
|
||||
</view>
|
||||
<view class="flex">
|
||||
<text>创建时间:</text>
|
||||
<uni-dateformat :date="goodList.submitTime" format="yyyy-MM-dd hh:mm:ss"></uni-dateformat>
|
||||
</view>
|
||||
</up-transition>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { ref } from 'vue'
|
||||
const show = ref(false)
|
||||
const goodList = ref({})
|
||||
|
||||
onShow(() => {
|
||||
goodList.value = JSON.parse(uni.getStorageSync('orderGoods'))
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10rpx 20rpx;
|
||||
|
||||
.text1 {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
|
||||
.h2 {
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-top: 20rpx;
|
||||
color: #999999;
|
||||
}
|
||||
</style>
|
77
common/Order/priceDetails.vue
Normal file
77
common/Order/priceDetails.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="content">
|
||||
<view class="h2">价格明细</view>
|
||||
<view>
|
||||
<up-transition :show="show">
|
||||
<view class="flex">
|
||||
<text>商品总价:</text>
|
||||
<text>¥{{goodList.total}}</text>
|
||||
</view>
|
||||
<!-- <view class="flex">
|
||||
<text>纸卷:</text>
|
||||
<text>¥{{goodList.wrapperPrice}}</text>
|
||||
</view> -->
|
||||
<view class="flex">
|
||||
<text>运费:</text>
|
||||
<text>¥{{goodList.freight}}</text>
|
||||
</view>
|
||||
<view class="flex">
|
||||
<text>优惠劵:</text>
|
||||
<text class="text1">减¥{{goodList.couponDiscount}}</text>
|
||||
</view>
|
||||
<view class="flex">
|
||||
<text>蚕宝豆抵扣:</text>
|
||||
<text class="text1">减¥{{goodList.pointsDiscount}}</text>
|
||||
</view>
|
||||
</up-transition>
|
||||
</view>
|
||||
<view class="flex">
|
||||
<view style="display: flex;align-items: center;" @click="show=!show">
|
||||
<text>实付款:</text>
|
||||
<up-icon name="arrow-up" color="#999999" size="20"></up-icon>
|
||||
</view>
|
||||
<view>
|
||||
<text class="text1">¥</text>
|
||||
<text class="text1" style="font-size: 40rpx;">{{goodList.actual}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { ref } from 'vue'
|
||||
const show = ref(false)
|
||||
const goodList = ref({})
|
||||
|
||||
onShow(() => {
|
||||
goodList.value = JSON.parse(uni.getStorageSync('orderGoods'))
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.flex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10rpx 20rpx;
|
||||
|
||||
.text1 {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
|
||||
.h2 {
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-top: 20rpx;
|
||||
color: #999999;
|
||||
}
|
||||
</style>
|
559
common/common.css
Normal file
559
common/common.css
Normal file
@ -0,0 +1,559 @@
|
||||
.fill-height {
|
||||
width: 100%;
|
||||
height: var(--status-bar-height);
|
||||
}
|
||||
|
||||
.uni-navbar .uni-navbar__content {
|
||||
border: 0 none !important;
|
||||
}
|
||||
|
||||
.uni-navbar .uni-navbar__header .uni-nav-bar-text {
|
||||
font-size: 36rpx;
|
||||
font-weight: 400;
|
||||
font-family: PingFang SC;
|
||||
}
|
||||
|
||||
/* 带有筛选项的标题 */
|
||||
.filter_title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
padding-left: 28rpx;
|
||||
}
|
||||
|
||||
.filter_title .go_back_icon {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
position: absolute;
|
||||
left: 28rpx;
|
||||
margin-top: -8rpx;
|
||||
}
|
||||
|
||||
.filter_title .filter_title_name {
|
||||
font-family: PingFang SC;
|
||||
font-size: 32rpx;
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translate(-50%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filter_title .filter_title_name>image {
|
||||
width: 26rpx;
|
||||
height: 14rpx;
|
||||
margin: 10rpx;
|
||||
transition: 0.3s all;
|
||||
}
|
||||
|
||||
.filter_title .filter_title_name .rotate_style {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.filter_title .titlt_select {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
top: 88rpx;
|
||||
}
|
||||
|
||||
.filter_title .titlt_select .titlt_div {
|
||||
width: 50%;
|
||||
height: auto;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.1);
|
||||
border-radius: 12rpx;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.filter_title .titlt_select .titlt_div>text {
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #F3F8FF;
|
||||
}
|
||||
|
||||
/* 列表页最外层样式 */
|
||||
.content_list {
|
||||
width: 100%;
|
||||
/* height: calc(100vh - 88rpx); */
|
||||
height: calc(100vh - 88rpx - var(--status-bar-height));
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.content_list .list_div_3 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: calc(100% - 136rpx - 76rpx - 104rpx);
|
||||
overflow: auto;
|
||||
box-sizing: border-box;
|
||||
padding: 40rpx 28rpx 0;
|
||||
background-color: #f3f8ff;
|
||||
}
|
||||
|
||||
.content_list .list_div_2 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: calc(100% - 104rpx - 104rpx);
|
||||
overflow: auto;
|
||||
box-sizing: border-box;
|
||||
padding: 40rpx 28rpx 0;
|
||||
background-color: #f3f8ff;
|
||||
}
|
||||
|
||||
.content_list .list_div_1 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: calc(100% - 104rpx - 40rpx);
|
||||
overflow: auto;
|
||||
box-sizing: border-box;
|
||||
padding: 40rpx 28rpx 0;
|
||||
background-color: #f3f8ff;
|
||||
}
|
||||
|
||||
/* 列表中卡片样式:标题-一行 */
|
||||
.list_title_1line {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 42rpx 28rpx;
|
||||
box-shadow: 0px 0px 12rpx rgba(0, 31, 80, 0.06);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.list_title_1line .list_title {
|
||||
width: 100%;
|
||||
height: 42rpx;
|
||||
font-size: 30rpx;
|
||||
font-family: PingFang SC;
|
||||
font-weight: 600;
|
||||
line-height: 42rpx;
|
||||
color: #1D1D1D;
|
||||
}
|
||||
|
||||
.list_title_1line .list_line {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin-top: 28rpx;
|
||||
}
|
||||
|
||||
.list_title_1line .list_line:last-child {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.list_title_1line .list_line>text {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
min-height: 32rpx;
|
||||
font-family: PingFang SC;
|
||||
font-size: 24rpx;
|
||||
color: #6e6e6e;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* 列表中卡片样式:标题-一行半 */
|
||||
.list_title_1_5line {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 42rpx 28rpx;
|
||||
box-shadow: 0px 0px 12rpx rgba(0, 31, 80, 0.06);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.list_title_1_5line .list_title {
|
||||
width: 100%;
|
||||
height: 42rpx;
|
||||
font-size: 30rpx;
|
||||
font-family: PingFang SC;
|
||||
font-weight: 600;
|
||||
line-height: 42rpx;
|
||||
color: #1D1D1D;
|
||||
}
|
||||
|
||||
.list_title_1_5line .list_line {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 28rpx;
|
||||
}
|
||||
|
||||
.list_title_1_5line .list_line:last-child {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.list_title_1_5line .list_line:last-child>text {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.list_title_1_5line .list_line>text {
|
||||
width: 50%;
|
||||
box-sizing: border-box;
|
||||
min-height: 32rpx;
|
||||
font-family: PingFang SC;
|
||||
font-size: 24rpx;
|
||||
color: #6e6e6e;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.list_title_1_5line .list_line>text:first-child {
|
||||
padding-right: 20rpx;
|
||||
}
|
||||
|
||||
/* 列表中卡片样式:标题-两行 */
|
||||
.list_title_2line {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 42rpx 28rpx;
|
||||
box-shadow: 0px 0px 12rpx rgba(0, 31, 80, 0.06);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.list_title_2line .list_title {
|
||||
width: 100%;
|
||||
height: 42rpx;
|
||||
font-size: 30rpx;
|
||||
font-family: PingFang SC;
|
||||
font-weight: 600;
|
||||
line-height: 42rpx;
|
||||
color: #1D1D1D;
|
||||
}
|
||||
|
||||
.list_title_2line .list_line {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 28rpx;
|
||||
}
|
||||
|
||||
.list_title_2line .list_line:last-child {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.list_title_2line .list_line>text {
|
||||
width: 50%;
|
||||
box-sizing: border-box;
|
||||
min-height: 32rpx;
|
||||
font-family: PingFang SC;
|
||||
font-size: 24rpx;
|
||||
color: #6e6e6e;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.list_title_2line .list_line>text:first-child {
|
||||
padding-right: 20rpx;
|
||||
}
|
||||
|
||||
/* 列表中卡片样式:标题-两行 加一个底部带上边框的 */
|
||||
.list_title_2line_bottom {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-sizing: border-box;
|
||||
padding-top: 42rpx;
|
||||
box-shadow: 0px 0px 12rpx rgba(0, 31, 80, 0.06);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.list_title_2line_bottom .list_title {
|
||||
width: 100%;
|
||||
height: 42rpx;
|
||||
font-size: 30rpx;
|
||||
font-family: PingFang SC;
|
||||
font-weight: 600;
|
||||
line-height: 42rpx;
|
||||
color: #1D1D1D;
|
||||
box-sizing: border-box;
|
||||
padding: 0 28rpx;
|
||||
}
|
||||
|
||||
.list_title_2line_bottom .list_line {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 28rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 0 28rpx;
|
||||
}
|
||||
|
||||
.list_title_2line_bottom .list_line:last-child {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.list_title_2line_bottom .list_line>text {
|
||||
width: 50%;
|
||||
box-sizing: border-box;
|
||||
min-height: 32rpx;
|
||||
font-family: PingFang SC;
|
||||
font-size: 24rpx;
|
||||
color: #6e6e6e;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.list_title_2line_bottom .list_line>text:first-child {
|
||||
padding-right: 20rpx;
|
||||
}
|
||||
|
||||
.list_title_2line_bottom .list_bottom {
|
||||
width: 100%;
|
||||
line-height: 90rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 0 28rpx;
|
||||
border-top: 2rpx solid #F3F8FF;
|
||||
margin-top: 28rpx;
|
||||
font-size: 24rpx;
|
||||
font-family: PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #1D1D1D;
|
||||
}
|
||||
|
||||
/* 列表中卡片样式:上下两块-上 左图片右内容 下 日期等 */
|
||||
.list_2block_image_content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0px 0px 12rpx rgba(0, 31, 80, 0.06);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 上部分 */
|
||||
.list_2block_image_content .top_block {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
box-sizing: border-box;
|
||||
padding: 42rpx 28rpx 28rpx;
|
||||
}
|
||||
|
||||
.list_2block_image_content .top_block .top_block_image {
|
||||
width: 144rpx;
|
||||
height: 144rpx;
|
||||
}
|
||||
|
||||
.list_2block_image_content .top_block .top_block_content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: calc(100% - 144rpx - 20rpx);
|
||||
margin-left: 20rpx;
|
||||
min-height: 142rpx;
|
||||
}
|
||||
|
||||
.list_2block_image_content .top_block .top_block_content .content_title {
|
||||
width: 100%;
|
||||
font-family: PingFang SC;
|
||||
font-size: 30rpx;
|
||||
color: #1d1d1d;
|
||||
}
|
||||
|
||||
.list_2block_image_content .top_block .top_block_content .content_line {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 32rpx;
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
|
||||
.list_2block_image_content .top_block .top_block_content .content_line:last-child {
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.list_2block_image_content .top_block .top_block_content .content_line>image {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.list_2block_image_content .top_block .top_block_content .content_line>text {
|
||||
width: calc(100% - 28rpx - 4rpx);
|
||||
margin-left: 4rpx;
|
||||
font-family: PingFang SC;
|
||||
font-size: 24rpx;
|
||||
color: #b2b2b2;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* 下部分 */
|
||||
.list_2block_image_content .bottom_block {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
padding: 0 28rpx;
|
||||
width: 100%;
|
||||
height: 90rpx;
|
||||
border-top: 2rpx solid #F3F8FF;
|
||||
}
|
||||
|
||||
.list_2block_image_content .bottom_block>text {
|
||||
font-family: PingFang SC;
|
||||
font-size: 24rpx;
|
||||
color: #1d1d1d;
|
||||
}
|
||||
|
||||
/* 列表卡片标签样式 */
|
||||
.list_position {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.list_position .label_Style {
|
||||
width: auto;
|
||||
line-height: 42rpx;
|
||||
padding: 0 20rpx;
|
||||
border-bottom-left-radius: 16rpx;
|
||||
border-top-right-radius: 16rpx;
|
||||
font-family: PingFang SC;
|
||||
font-size: 24rpx;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* tabs切换:居中样式 */
|
||||
.tabs_center {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 28rpx 28rpx;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.tabs_center .tabs_div {
|
||||
min-width: 112rpx;
|
||||
line-height: 72rpx;
|
||||
font-family: PingFang SC;
|
||||
text-align: center;
|
||||
font-style: Regular;
|
||||
font-size: 30rpx;
|
||||
color: #1d1d1d;
|
||||
}
|
||||
|
||||
.tabs_center .tabs_div_select {
|
||||
color: #4285F4;
|
||||
border-bottom: 8rpx solid #4285F4;
|
||||
}
|
||||
|
||||
/* tabs切换:居左样式 */
|
||||
.tabs_left {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 28rpx 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.tabs_left .tabs_div {
|
||||
min-width: 112rpx;
|
||||
line-height: 72rpx;
|
||||
font-family: PingFang SC;
|
||||
text-align: center;
|
||||
font-style: Regular;
|
||||
font-size: 28rpx;
|
||||
color: #6E6E6E;
|
||||
margin-right: 40rpx;
|
||||
}
|
||||
|
||||
.tabs_left .tabs_div_select {
|
||||
color: #4285F4;
|
||||
border-bottom: 8rpx solid #4285F4;
|
||||
}
|
||||
|
||||
/* 列表上方搜索样式 */
|
||||
.list_search {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: calc(100% - 28rpx - 28rpx);
|
||||
box-sizing: border-box;
|
||||
height: 76rpx;
|
||||
margin: 28rpx 28rpx 0;
|
||||
background-color: #F3F8FF;
|
||||
border-radius: 8rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.list_search .search_text {
|
||||
flex: 1;
|
||||
min-height: 32rpx;
|
||||
font-family: PingFang SC;
|
||||
font-size: 24rpx;
|
||||
color: #ccd2dc;
|
||||
}
|
||||
|
||||
.list_search .search_icon {
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
}
|
||||
|
||||
/* 详情-左标题 右内容 布局 */
|
||||
.detail_title_content {
|
||||
width: 100%;
|
||||
/* height: calc(100vh - 88rpx); */
|
||||
height: 100vh;
|
||||
overflow: auto;
|
||||
box-sizing: border-box;
|
||||
padding: 40rpx 28rpx 0;
|
||||
}
|
||||
|
||||
.detail_title_content .title_content {
|
||||
width: 100%;
|
||||
line-height: 40rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.detail_title_content .title_content .left_title {
|
||||
font-family: PingFang SC;
|
||||
font-size: 28rpx;
|
||||
color: #1d1d1d;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.detail_title_content .title_content .right_content {
|
||||
font-family: PingFang SC;
|
||||
font-size: 28rpx;
|
||||
color: #1d1d1d;
|
||||
word-break: break-word;
|
||||
margin-left: 40rpx;
|
||||
text-align: right;
|
||||
font-weight: 400;
|
||||
}
|
16
common/http/config.ts
Normal file
16
common/http/config.ts
Normal file
@ -0,0 +1,16 @@
|
||||
export default {
|
||||
|
||||
//正式接口
|
||||
// base_url:'https://mall.goodsilk.cn/api',
|
||||
|
||||
//测试服务器
|
||||
// base_url: 'http://cs-piaowu.fangshangqu.net:10021/api/',
|
||||
// upload_img_url: 'http://cs-piaowu.fangshangqu.net:10021/api/sys/common/upload',
|
||||
// base_url:'http://192.168.2.65:10021/api/',
|
||||
// upload_img_url: 'http://192.168.2.65:10021/api/sys/common/upload',
|
||||
|
||||
//本地服务
|
||||
|
||||
base_url: 'http://192.168.1.222:8082',
|
||||
|
||||
}
|
33
common/http/index.ts
Normal file
33
common/http/index.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import httpRequest from '../http/interface'
|
||||
|
||||
export const postAction = (url : string, data = {}, headerCustom = {}) => {
|
||||
return httpRequest(
|
||||
url,
|
||||
'POST',
|
||||
data,
|
||||
headerCustom,
|
||||
)
|
||||
}
|
||||
export const getAction = (url : string, data = {}, headerCustom = {}) => {
|
||||
return httpRequest(
|
||||
url,
|
||||
'GET',
|
||||
data,
|
||||
headerCustom,
|
||||
)
|
||||
}
|
||||
export const putAction = (url : string, data = {}) => {
|
||||
return httpRequest(
|
||||
url,
|
||||
'PUT',
|
||||
data
|
||||
)
|
||||
}
|
||||
export const deleteAction = (url : string, data = {}) => {
|
||||
return httpRequest(
|
||||
url,
|
||||
'DELETE',
|
||||
data
|
||||
)
|
||||
}
|
||||
// 默认全部导出 import api from '@/common/vmeitime-http/'
|
244
common/http/interface.ts
Normal file
244
common/http/interface.ts
Normal file
@ -0,0 +1,244 @@
|
||||
/**
|
||||
* 通用uni-app网络请求
|
||||
* 基于 Promise 对象实现更简单的 request 使用方式,支持请求和响应拦截
|
||||
*/
|
||||
/*
|
||||
|
||||
*/
|
||||
import myconfig from '../http/config'
|
||||
|
||||
// 封装uni.request方法
|
||||
function httpRequest(url : string, method : any, data = {}, headerCustom = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const token = uni.getStorageSync('token')
|
||||
// 设置请求头
|
||||
const header = {
|
||||
// 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
|
||||
'Content-Type': 'application/json;charset=UTF-8',
|
||||
'Authorization': 'Bearer ' + token // 如果需要的话,可以在这里添加认证token
|
||||
};
|
||||
// 合并请求头
|
||||
const finalHeader = Object.assign({}, header, headerCustom);
|
||||
uni.setStorageSync('baseURL', myconfig.base_url)
|
||||
uni.request({
|
||||
url: myconfig.base_url + url, // 拼接基础URL和请求路径
|
||||
method: method,
|
||||
data: data, // 如果是GET请求,data应该为null
|
||||
header: finalHeader,
|
||||
success: (res) => {
|
||||
// 如果服务器返回的状态码为200,则认为是成功的响应
|
||||
if (res.data && res.statusCode === 200) {
|
||||
resolve(res.data);
|
||||
}else if(res.data && res.statusCode === 401){
|
||||
uni.showToast({
|
||||
icon:'error',
|
||||
title:'网络出错了!'
|
||||
})
|
||||
reject(new Error('请求失败: ' + (res.data && res.data?.message || '未知错误')));
|
||||
}else {
|
||||
reject(new Error('请求失败: ' + (res.data && res.data?.message || '未知错误')));
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export default httpRequest;
|
||||
|
||||
|
||||
// const config = {
|
||||
// baseUrl: myconfig.base_url,
|
||||
// header: {
|
||||
// 'Content-Type': 'application/json;charset=UTF-8',
|
||||
// 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
|
||||
// },
|
||||
// data: {},
|
||||
// method: "POST",
|
||||
// dataType: "json",
|
||||
// /* 如设为json,会对返回的数据做一次 JSON.parse */
|
||||
// responseType: "text",
|
||||
// success() { },
|
||||
// fail() { },
|
||||
// complete() { }
|
||||
// }
|
||||
// // 拦截器
|
||||
// const interceptor = {
|
||||
// request: null, //请求
|
||||
// response: null //响应
|
||||
// }
|
||||
// const request = (options) => {
|
||||
// if (!options) {
|
||||
// options = {}
|
||||
// }
|
||||
// uni.showLoading({
|
||||
// title: '操作中'
|
||||
// })
|
||||
// options.baseUrl = options.baseUrl || config.baseUrl
|
||||
// options.dataType = options.dataType || config.dataType
|
||||
// options.url = options.baseUrl + options.url
|
||||
// options.sslVerify = false
|
||||
// options.data = options.data || {}
|
||||
// options.method = options.method || config.method
|
||||
// if (options.dataType == 'json') {
|
||||
// options.header = {
|
||||
// ...options.header,
|
||||
// 'Content-Type': 'application/json;charset=UTF-8',
|
||||
// }
|
||||
// } else {
|
||||
// options.header = {
|
||||
// ...options.header,
|
||||
// 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
|
||||
// }
|
||||
// }
|
||||
// options.header = {
|
||||
// ...options.header,
|
||||
// 'X-Access-Token': uni.getStorageSync('token') || '',
|
||||
// }
|
||||
|
||||
// return new Promise((resolve, reject) => {
|
||||
// let _config = null
|
||||
// options.complete = (response) => {
|
||||
// uni.hideLoading()
|
||||
// let statusCode = response.statusCode
|
||||
// response.config = _config
|
||||
|
||||
// if (interceptor.response) {
|
||||
// let newResponse = interceptor.response(response)
|
||||
// if (newResponse) {
|
||||
// response = newResponse
|
||||
// }
|
||||
// }
|
||||
// // 统一的响应日志记录
|
||||
// _reslog(response)
|
||||
// if (statusCode === 200) { //成功
|
||||
// uni.$emit('login', {
|
||||
// login: true
|
||||
// });
|
||||
// if (response.data.code == 401) {
|
||||
// uni.setStorageSync('token', '')
|
||||
// // uni.reLaunch({
|
||||
// // url: '/pages/login/login'
|
||||
// // })
|
||||
// }
|
||||
// resolve(response.data);
|
||||
// } else if (statusCode === 401) {
|
||||
// // uni.clearStorageSync()
|
||||
// uni.setStorageSync('token', '')
|
||||
// // uni.reLaunch({
|
||||
// // url: '/pages/login/login'
|
||||
// // })
|
||||
// } else {
|
||||
// reject(response)
|
||||
// // console.log(JSON.stringify(response));
|
||||
// // console.log("login err=: ", response);
|
||||
// }
|
||||
// }
|
||||
|
||||
// _config = Object.assign({}, config, options)
|
||||
// _config.requestId = new Date().getTime()
|
||||
|
||||
// if (interceptor.request) {
|
||||
// interceptor.request(_config)
|
||||
// }
|
||||
|
||||
// // 统一的请求日志记录
|
||||
// _reqlog(_config)
|
||||
|
||||
// if (process.env.NODE_ENV === 'development') {
|
||||
// // console.log("【" + _config.requestId + "】 地址:" + _config.url)
|
||||
// if (_config.data) {
|
||||
// // console.log("【" + _config.requestId + "】 参数:" + JSON.stringify(_config.data))
|
||||
// }
|
||||
// }
|
||||
|
||||
// uni.request(_config);
|
||||
// });
|
||||
// }
|
||||
// const get = (url, data, options) => {
|
||||
// if (!options) {
|
||||
// options = {}
|
||||
// }
|
||||
// options.url = url
|
||||
// options.data = data
|
||||
// options.method = 'GET'
|
||||
// return request(options)
|
||||
// }
|
||||
// const post(url, data, options) => {
|
||||
// if (!options) {
|
||||
// options = {}
|
||||
// }
|
||||
// options.url = url
|
||||
// options.data = data
|
||||
// options.method = 'POST'
|
||||
// return request(options)
|
||||
// }
|
||||
// const put = (url, data, options) => {
|
||||
// if (!options) {
|
||||
// options = {}
|
||||
// }
|
||||
// options.url = url
|
||||
// options.data = data
|
||||
// options.method = 'PUT'
|
||||
// return request(options)
|
||||
// }
|
||||
// const delete=(url, data, options) => {
|
||||
// if (!options) {
|
||||
// options = {}
|
||||
// }
|
||||
// options.url = url
|
||||
// options.data = data
|
||||
// options.method = 'DELETE'
|
||||
// return request(options)
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
// /**
|
||||
// * 请求接口日志记录
|
||||
// */
|
||||
// function _reqlog(req) {
|
||||
// if (process.env.NODE_ENV === 'development') {
|
||||
// // console.log("【" + req.requestId + "】 地址:" + req.url)
|
||||
|
||||
// // if (req.statusCode == '401') {
|
||||
// // uni.reLaunch({
|
||||
// // url: '/pages/login/login'
|
||||
// // });
|
||||
// // }
|
||||
|
||||
// if (req.data) {
|
||||
// // console.log("【" + req.requestId + "】 请求参数:" + JSON.stringify(req.data))
|
||||
// }
|
||||
// }
|
||||
// //TODO 调接口异步写入日志数据库
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 响应接口日志记录
|
||||
// */
|
||||
// function _reslog(res) {
|
||||
// let _statusCode = res.statusCode;
|
||||
// // if (process.env.NODE_ENV === 'development') {
|
||||
// // console.log("【" + res.config.requestId + "】 地址:" + res.config.url)
|
||||
// // if (res.config.data) {
|
||||
// // console.log("【" + res.config.requestId + "】 请求参数:" + JSON.stringify(res.config.data))
|
||||
// // }
|
||||
// // console.log("【" + res.config.requestId + "】 响应结果:" + JSON.stringify(res))
|
||||
// // }
|
||||
// //TODO 除了接口服务错误外,其他日志调接口异步写入日志数据库
|
||||
// switch (_statusCode) {
|
||||
// case 200:
|
||||
// break;
|
||||
// case 401:
|
||||
// break;
|
||||
// case 404:
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// export default request;
|
56
node_modules/.package-lock.json
generated
vendored
56
node_modules/.package-lock.json
generated
vendored
@ -55,6 +55,16 @@
|
||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/dom-webcodecs": {
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmmirror.com/@types/dom-webcodecs/-/dom-webcodecs-0.1.13.tgz",
|
||||
"integrity": "sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ=="
|
||||
},
|
||||
"node_modules/@types/emscripten": {
|
||||
"version": "1.39.13",
|
||||
"resolved": "https://registry.npmmirror.com/@types/emscripten/-/emscripten-1.39.13.tgz",
|
||||
"integrity": "sha512-cFq+fO/isvhvmuP/+Sl4K4jtU6E23DoivtbO4r50e3odaxAiVdbfSYRDdJ4gCdxx+3aRjhphS5ZMwIH4hFy/Cw=="
|
||||
},
|
||||
"node_modules/@vant/popperjs": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz",
|
||||
@ -167,6 +177,15 @@
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.13.tgz",
|
||||
"integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ=="
|
||||
},
|
||||
"node_modules/barcode-detector": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/barcode-detector/-/barcode-detector-2.2.2.tgz",
|
||||
"integrity": "sha512-JcSekql+EV93evfzF9zBr+Y6aRfkR+QFvgyzbwQ0dbymZXoAI9+WgT7H1E429f+3RKNncHz2CW98VQtaaKpmfQ==",
|
||||
"dependencies": {
|
||||
"@types/dom-webcodecs": "^0.1.11",
|
||||
"zxing-wasm": "1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
|
||||
@ -252,6 +271,11 @@
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/sdp": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/sdp/-/sdp-3.2.0.tgz",
|
||||
"integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw=="
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
@ -294,6 +318,38 @@
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vue-qrcode-reader": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/vue-qrcode-reader/-/vue-qrcode-reader-5.6.0.tgz",
|
||||
"integrity": "sha512-uvaJqMRgR/1tt7XWAqaRBQf0mo3gudu5fXqZmtoq+87lvmM4dublJ7StO6ssNO3FaJqssG72hPhXWoBoYWJIeg==",
|
||||
"dependencies": {
|
||||
"barcode-detector": "2.2.2",
|
||||
"webrtc-adapter": "8.2.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webrtc-adapter": {
|
||||
"version": "8.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/webrtc-adapter/-/webrtc-adapter-8.2.3.tgz",
|
||||
"integrity": "sha512-gnmRz++suzmvxtp3ehQts6s2JtAGPuDPjA1F3a9ckNpG1kYdYuHWYpazoAnL9FS5/B21tKlhkorbdCXat0+4xQ==",
|
||||
"dependencies": {
|
||||
"sdp": "^3.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0",
|
||||
"npm": ">=3.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/zxing-wasm": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/zxing-wasm/-/zxing-wasm-1.1.3.tgz",
|
||||
"integrity": "sha512-MYm9k/5YVs4ZOTIFwlRjfFKD0crhefgbnt1+6TEpmKUDFp3E2uwqGSKwQOd2hOIsta/7Usq4hnpNRYTLoljnfA==",
|
||||
"dependencies": {
|
||||
"@types/emscripten": "^1.39.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
21
node_modules/@types/dom-webcodecs/LICENSE
generated
vendored
Normal file
21
node_modules/@types/dom-webcodecs/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
15
node_modules/@types/dom-webcodecs/README.md
generated
vendored
Normal file
15
node_modules/@types/dom-webcodecs/README.md
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# Installation
|
||||
> `npm install --save @types/dom-webcodecs`
|
||||
|
||||
# Summary
|
||||
This package contains type definitions for dom-webcodecs (https://w3c.github.io/webcodecs/).
|
||||
|
||||
# Details
|
||||
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/dom-webcodecs.
|
||||
|
||||
### Additional Details
|
||||
* Last updated: Tue, 08 Oct 2024 09:36:58 GMT
|
||||
* Dependencies: none
|
||||
|
||||
# Credits
|
||||
These definitions were written by [Ben Wagner](https://github.com/dogben).
|
185
node_modules/@types/dom-webcodecs/index.d.ts
generated
vendored
Normal file
185
node_modules/@types/dom-webcodecs/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,185 @@
|
||||
// Versioning:
|
||||
// Until the WebCodecs spec is finalized, the major version number is 0. I have chosen to use minor
|
||||
// version 1 to denote the API as defined by the IDL files from the Chromium repo at
|
||||
// https://chromium.googlesource.com/chromium/src/+/main/third_party/blink/renderer/modules/webcodecs.
|
||||
// Please use a version number above 0.1 if using the spec at https://w3c.github.io/webcodecs/ as
|
||||
// the source.
|
||||
|
||||
// The declarations in webcodecs.generated.d.ts have been generated using the code in
|
||||
// https://github.com/yume-chan/webcodecs-lib-generator. See
|
||||
// https://github.com/yume-chan/webcodecs-lib-generator/blob/main/README.md for more detail.
|
||||
/// <reference path="./webcodecs.generated.d.ts" />
|
||||
|
||||
// The following declarations are copied from
|
||||
// https://github.com/microsoft/TypeScript-DOM-lib-generator/blob/a75338e1ea8a958bf08a5745141d2ab8f14ba2ca/baselines/dom.generated.d.ts
|
||||
// and modified to expand the types to include VideoFrame.
|
||||
|
||||
/** Shim for OffscreenCanvas, which was removed in TS 4.4 */
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
interface OffscreenCanvas extends EventTarget {
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces CanvasImageSource; only applies if WebCodecs is available.
|
||||
*/
|
||||
type CanvasImageSourceWebCodecs =
|
||||
| HTMLOrSVGImageElement
|
||||
| HTMLVideoElement
|
||||
| HTMLCanvasElement
|
||||
| ImageBitmap
|
||||
| OffscreenCanvas
|
||||
| VideoFrame;
|
||||
|
||||
interface CanvasRenderingContext2D {
|
||||
drawImage(image: CanvasImageSourceWebCodecs, dx: number, dy: number): void;
|
||||
drawImage(image: CanvasImageSourceWebCodecs, dx: number, dy: number, dw: number, dh: number): void;
|
||||
drawImage(
|
||||
image: CanvasImageSourceWebCodecs,
|
||||
sx: number,
|
||||
sy: number,
|
||||
sw: number,
|
||||
sh: number,
|
||||
dx: number,
|
||||
dy: number,
|
||||
dw: number,
|
||||
dh: number,
|
||||
): void;
|
||||
createPattern(image: CanvasImageSourceWebCodecs, repetition: string | null): CanvasPattern | null;
|
||||
}
|
||||
|
||||
interface OffscreenCanvasRenderingContext2D {
|
||||
drawImage(image: CanvasImageSourceWebCodecs, dx: number, dy: number): void;
|
||||
drawImage(image: CanvasImageSourceWebCodecs, dx: number, dy: number, dw: number, dh: number): void;
|
||||
drawImage(
|
||||
image: CanvasImageSourceWebCodecs,
|
||||
sx: number,
|
||||
sy: number,
|
||||
sw: number,
|
||||
sh: number,
|
||||
dx: number,
|
||||
dy: number,
|
||||
dw: number,
|
||||
dh: number,
|
||||
): void;
|
||||
createPattern(image: CanvasImageSourceWebCodecs, repetition: string | null): CanvasPattern | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces ImageBitmapSource; only applies if WebCodecs is available.
|
||||
*/
|
||||
type ImageBitmapSourceWebCodecs = CanvasImageSourceWebCodecs | Blob | ImageData;
|
||||
|
||||
declare function createImageBitmap(
|
||||
image: ImageBitmapSourceWebCodecs,
|
||||
options?: ImageBitmapOptions,
|
||||
): Promise<ImageBitmap>;
|
||||
declare function createImageBitmap(
|
||||
image: ImageBitmapSourceWebCodecs,
|
||||
sx: number,
|
||||
sy: number,
|
||||
sw: number,
|
||||
sh: number,
|
||||
options?: ImageBitmapOptions,
|
||||
): Promise<ImageBitmap>;
|
||||
|
||||
/**
|
||||
* Replaces TexImageSource; only applies if WebCodecs is available.
|
||||
*/
|
||||
type TexImageSourceWebCodecs =
|
||||
| ImageBitmap
|
||||
| ImageData
|
||||
| HTMLImageElement
|
||||
| HTMLCanvasElement
|
||||
| HTMLVideoElement
|
||||
| OffscreenCanvas
|
||||
| VideoFrame;
|
||||
|
||||
interface WebGLRenderingContextOverloads {
|
||||
texImage2D(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
internalformat: GLint,
|
||||
format: GLenum,
|
||||
type: GLenum,
|
||||
source: TexImageSourceWebCodecs,
|
||||
): void;
|
||||
texSubImage2D(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
xoffset: GLint,
|
||||
yoffset: GLint,
|
||||
format: GLenum,
|
||||
type: GLenum,
|
||||
source: TexImageSourceWebCodecs,
|
||||
): void;
|
||||
}
|
||||
|
||||
interface WebGL2RenderingContextBase {
|
||||
texImage3D(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
internalformat: GLint,
|
||||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
depth: GLsizei,
|
||||
border: GLint,
|
||||
format: GLenum,
|
||||
type: GLenum,
|
||||
source: TexImageSourceWebCodecs,
|
||||
): void;
|
||||
texSubImage3D(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
xoffset: GLint,
|
||||
yoffset: GLint,
|
||||
zoffset: GLint,
|
||||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
depth: GLsizei,
|
||||
format: GLenum,
|
||||
type: GLenum,
|
||||
source: TexImageSourceWebCodecs,
|
||||
): void;
|
||||
}
|
||||
|
||||
interface WebGL2RenderingContextOverloads {
|
||||
texImage2D(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
internalformat: GLint,
|
||||
format: GLenum,
|
||||
type: GLenum,
|
||||
source: TexImageSourceWebCodecs,
|
||||
): void;
|
||||
texImage2D(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
internalformat: GLint,
|
||||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
border: GLint,
|
||||
format: GLenum,
|
||||
type: GLenum,
|
||||
source: TexImageSourceWebCodecs,
|
||||
): void;
|
||||
texSubImage2D(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
xoffset: GLint,
|
||||
yoffset: GLint,
|
||||
format: GLenum,
|
||||
type: GLenum,
|
||||
source: TexImageSourceWebCodecs,
|
||||
): void;
|
||||
texSubImage2D(
|
||||
target: GLenum,
|
||||
level: GLint,
|
||||
xoffset: GLint,
|
||||
yoffset: GLint,
|
||||
width: GLsizei,
|
||||
height: GLsizei,
|
||||
format: GLenum,
|
||||
type: GLenum,
|
||||
source: TexImageSourceWebCodecs,
|
||||
): void;
|
||||
}
|
26
node_modules/@types/dom-webcodecs/package.json
generated
vendored
Normal file
26
node_modules/@types/dom-webcodecs/package.json
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "@types/dom-webcodecs",
|
||||
"version": "0.1.13",
|
||||
"description": "TypeScript definitions for dom-webcodecs",
|
||||
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/dom-webcodecs",
|
||||
"license": "MIT",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Ben Wagner",
|
||||
"githubUsername": "dogben",
|
||||
"url": "https://github.com/dogben"
|
||||
}
|
||||
],
|
||||
"main": "",
|
||||
"types": "index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
|
||||
"directory": "types/dom-webcodecs"
|
||||
},
|
||||
"scripts": {},
|
||||
"dependencies": {},
|
||||
"typesPublisherContentHash": "6636871774b310b05e6e4866ff18e837c547c0355726d08095658258522293f7",
|
||||
"typeScriptVersion": "5.7",
|
||||
"nonNpm": true
|
||||
}
|
517
node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts
generated
vendored
Normal file
517
node_modules/@types/dom-webcodecs/webcodecs.generated.d.ts
generated
vendored
Normal file
@ -0,0 +1,517 @@
|
||||
/////////////////////////////
|
||||
/// webcodecs APIs
|
||||
/////////////////////////////
|
||||
|
||||
interface AudioDataCopyToOptions {
|
||||
format?: AudioSampleFormat | undefined;
|
||||
frameCount?: number | undefined;
|
||||
frameOffset?: number | undefined;
|
||||
planeIndex: number;
|
||||
}
|
||||
|
||||
interface AudioDataInit {
|
||||
data: AllowSharedBufferSource;
|
||||
format: AudioSampleFormat;
|
||||
numberOfChannels: number;
|
||||
numberOfFrames: number;
|
||||
sampleRate: number;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
interface AudioDecoderConfig {
|
||||
codec: string;
|
||||
description?: AllowSharedBufferSource | undefined;
|
||||
numberOfChannels: number;
|
||||
sampleRate: number;
|
||||
}
|
||||
|
||||
interface AudioDecoderInit {
|
||||
error: WebCodecsErrorCallback;
|
||||
output: AudioDataOutputCallback;
|
||||
}
|
||||
|
||||
interface AudioDecoderSupport {
|
||||
config?: AudioDecoderConfig;
|
||||
supported?: boolean;
|
||||
}
|
||||
|
||||
interface AudioEncoderConfig {
|
||||
bitrate?: number | undefined;
|
||||
codec: string;
|
||||
numberOfChannels: number;
|
||||
sampleRate: number;
|
||||
}
|
||||
|
||||
interface AudioEncoderInit {
|
||||
error: WebCodecsErrorCallback;
|
||||
output: EncodedAudioChunkOutputCallback;
|
||||
}
|
||||
|
||||
interface AudioEncoderSupport {
|
||||
config?: AudioEncoderConfig;
|
||||
supported?: boolean;
|
||||
}
|
||||
|
||||
interface AvcEncoderConfig {
|
||||
format?: AvcBitstreamFormat | undefined;
|
||||
}
|
||||
|
||||
interface EncodedAudioChunkInit {
|
||||
data: AllowSharedBufferSource;
|
||||
duration?: number | undefined;
|
||||
timestamp: number;
|
||||
type: EncodedAudioChunkType;
|
||||
}
|
||||
|
||||
interface EncodedAudioChunkMetadata {
|
||||
decoderConfig?: AudioDecoderConfig | undefined;
|
||||
}
|
||||
|
||||
interface EncodedVideoChunkInit {
|
||||
data: AllowSharedBufferSource;
|
||||
duration?: number | undefined;
|
||||
timestamp: number;
|
||||
type: EncodedVideoChunkType;
|
||||
}
|
||||
|
||||
interface EncodedVideoChunkMetadata {
|
||||
decoderConfig?: VideoDecoderConfig | undefined;
|
||||
temporalLayerId?: number | undefined;
|
||||
}
|
||||
|
||||
interface ImageDecodeOptions {
|
||||
completeFramesOnly?: boolean | undefined;
|
||||
frameIndex?: number | undefined;
|
||||
}
|
||||
|
||||
interface ImageDecodeResult {
|
||||
complete: boolean;
|
||||
image: VideoFrame;
|
||||
}
|
||||
|
||||
interface ImageDecoderInit {
|
||||
colorSpaceConversion?: ColorSpaceConversion | undefined;
|
||||
data: ImageBufferSource;
|
||||
desiredHeight?: number | undefined;
|
||||
desiredWidth?: number | undefined;
|
||||
preferAnimation?: boolean | undefined;
|
||||
premultiplyAlpha?: PremultiplyAlpha | undefined;
|
||||
type: string;
|
||||
}
|
||||
|
||||
interface PlaneLayout {
|
||||
offset: number;
|
||||
stride: number;
|
||||
}
|
||||
|
||||
interface VideoColorSpaceInit {
|
||||
fullRange?: boolean | null | undefined;
|
||||
matrix?: VideoMatrixCoefficients | null | undefined;
|
||||
primaries?: VideoColorPrimaries | null | undefined;
|
||||
transfer?: VideoTransferCharacteristics | null | undefined;
|
||||
}
|
||||
|
||||
interface VideoDecoderConfig {
|
||||
codec: string;
|
||||
codedHeight?: number | undefined;
|
||||
codedWidth?: number | undefined;
|
||||
colorSpace?: VideoColorSpaceInit | undefined;
|
||||
description?: AllowSharedBufferSource | undefined;
|
||||
displayAspectHeight?: number | undefined;
|
||||
displayAspectWidth?: number | undefined;
|
||||
hardwareAcceleration?: HardwarePreference | undefined;
|
||||
optimizeForLatency?: boolean | undefined;
|
||||
}
|
||||
|
||||
interface VideoDecoderInit {
|
||||
error: WebCodecsErrorCallback;
|
||||
output: VideoFrameOutputCallback;
|
||||
}
|
||||
|
||||
interface VideoDecoderSupport {
|
||||
config?: VideoDecoderConfig;
|
||||
supported?: boolean;
|
||||
}
|
||||
|
||||
interface VideoEncoderConfig {
|
||||
alpha?: AlphaOption | undefined;
|
||||
avc?: AvcEncoderConfig | undefined;
|
||||
bitrate?: number | undefined;
|
||||
bitrateMode?: VideoEncoderBitrateMode | undefined;
|
||||
codec: string;
|
||||
displayHeight?: number | undefined;
|
||||
displayWidth?: number | undefined;
|
||||
framerate?: number | undefined;
|
||||
hardwareAcceleration?: HardwarePreference | undefined;
|
||||
height: number;
|
||||
latencyMode?: LatencyMode | undefined;
|
||||
scalabilityMode?: string | undefined;
|
||||
width: number;
|
||||
}
|
||||
|
||||
interface VideoEncoderEncodeOptions {
|
||||
keyFrame?: boolean;
|
||||
}
|
||||
|
||||
interface VideoEncoderInit {
|
||||
error: WebCodecsErrorCallback;
|
||||
output: EncodedVideoChunkOutputCallback;
|
||||
}
|
||||
|
||||
interface VideoEncoderSupport {
|
||||
config?: VideoEncoderConfig;
|
||||
supported?: boolean;
|
||||
}
|
||||
|
||||
interface VideoFrameBufferInit {
|
||||
codedHeight: number;
|
||||
codedWidth: number;
|
||||
colorSpace?: VideoColorSpaceInit | undefined;
|
||||
displayHeight?: number | undefined;
|
||||
displayWidth?: number | undefined;
|
||||
duration?: number | undefined;
|
||||
format: VideoPixelFormat;
|
||||
layout?: PlaneLayout[] | undefined;
|
||||
timestamp: number;
|
||||
visibleRect?: DOMRectInit | undefined;
|
||||
}
|
||||
|
||||
interface VideoFrameCopyToOptions {
|
||||
layout?: PlaneLayout[] | undefined;
|
||||
rect?: DOMRectInit | undefined;
|
||||
}
|
||||
|
||||
interface VideoFrameInit {
|
||||
alpha?: AlphaOption | undefined;
|
||||
displayHeight?: number | undefined;
|
||||
displayWidth?: number | undefined;
|
||||
duration?: number | undefined;
|
||||
timestamp?: number | undefined;
|
||||
visibleRect?: DOMRectInit | undefined;
|
||||
}
|
||||
|
||||
interface AudioData {
|
||||
readonly duration: number;
|
||||
readonly format: AudioSampleFormat | null;
|
||||
readonly numberOfChannels: number;
|
||||
readonly numberOfFrames: number;
|
||||
readonly sampleRate: number;
|
||||
readonly timestamp: number;
|
||||
allocationSize(options: AudioDataCopyToOptions): number;
|
||||
clone(): AudioData;
|
||||
close(): void;
|
||||
copyTo(destination: AllowSharedBufferSource, options: AudioDataCopyToOptions): void;
|
||||
}
|
||||
|
||||
declare var AudioData: {
|
||||
prototype: AudioData;
|
||||
new(init: AudioDataInit): AudioData;
|
||||
};
|
||||
|
||||
interface AudioDecoderEventMap {
|
||||
"dequeue": Event;
|
||||
}
|
||||
|
||||
/** Available only in secure contexts. */
|
||||
interface AudioDecoder {
|
||||
readonly decodeQueueSize: number;
|
||||
readonly state: CodecState;
|
||||
ondequeue: ((this: AudioDecoder, ev: Event) => any) | null;
|
||||
close(): void;
|
||||
configure(config: AudioDecoderConfig): void;
|
||||
decode(chunk: EncodedAudioChunk): void;
|
||||
flush(): Promise<void>;
|
||||
reset(): void;
|
||||
addEventListener<K extends keyof AudioDecoderEventMap>(
|
||||
type: K,
|
||||
listener: (this: AudioDecoder, ev: AudioDecoderEventMap[K]) => any,
|
||||
options?: boolean | AddEventListenerOptions,
|
||||
): void;
|
||||
addEventListener(
|
||||
type: string,
|
||||
listener: EventListenerOrEventListenerObject,
|
||||
options?: boolean | AddEventListenerOptions,
|
||||
): void;
|
||||
removeEventListener<K extends keyof AudioDecoderEventMap>(
|
||||
type: K,
|
||||
listener: (this: AudioDecoder, ev: AudioDecoderEventMap[K]) => any,
|
||||
options?: boolean | EventListenerOptions,
|
||||
): void;
|
||||
removeEventListener(
|
||||
type: string,
|
||||
listener: EventListenerOrEventListenerObject,
|
||||
options?: boolean | EventListenerOptions,
|
||||
): void;
|
||||
}
|
||||
|
||||
declare var AudioDecoder: {
|
||||
prototype: AudioDecoder;
|
||||
new(init: AudioDecoderInit): AudioDecoder;
|
||||
isConfigSupported(config: AudioDecoderConfig): Promise<AudioDecoderSupport>;
|
||||
};
|
||||
|
||||
interface AudioEncoderEventMap {
|
||||
"dequeue": Event;
|
||||
}
|
||||
|
||||
/** Available only in secure contexts. */
|
||||
interface AudioEncoder {
|
||||
readonly encodeQueueSize: number;
|
||||
readonly state: CodecState;
|
||||
ondequeue: ((this: AudioEncoder, ev: Event) => any) | null;
|
||||
close(): void;
|
||||
configure(config: AudioEncoderConfig): void;
|
||||
encode(data: AudioData): void;
|
||||
flush(): Promise<void>;
|
||||
reset(): void;
|
||||
addEventListener<K extends keyof AudioEncoderEventMap>(
|
||||
type: K,
|
||||
listener: (this: AudioEncoder, ev: AudioEncoderEventMap[K]) => any,
|
||||
options?: boolean | AddEventListenerOptions,
|
||||
): void;
|
||||
addEventListener(
|
||||
type: string,
|
||||
listener: EventListenerOrEventListenerObject,
|
||||
options?: boolean | AddEventListenerOptions,
|
||||
): void;
|
||||
removeEventListener<K extends keyof AudioEncoderEventMap>(
|
||||
type: K,
|
||||
listener: (this: AudioEncoder, ev: AudioEncoderEventMap[K]) => any,
|
||||
options?: boolean | EventListenerOptions,
|
||||
): void;
|
||||
removeEventListener(
|
||||
type: string,
|
||||
listener: EventListenerOrEventListenerObject,
|
||||
options?: boolean | EventListenerOptions,
|
||||
): void;
|
||||
}
|
||||
|
||||
declare var AudioEncoder: {
|
||||
prototype: AudioEncoder;
|
||||
new(init: AudioEncoderInit): AudioEncoder;
|
||||
isConfigSupported(config: AudioEncoderConfig): Promise<AudioEncoderSupport>;
|
||||
};
|
||||
|
||||
interface EncodedAudioChunk {
|
||||
readonly byteLength: number;
|
||||
readonly duration: number | null;
|
||||
readonly timestamp: number;
|
||||
readonly type: EncodedAudioChunkType;
|
||||
copyTo(destination: AllowSharedBufferSource): void;
|
||||
}
|
||||
|
||||
declare var EncodedAudioChunk: {
|
||||
prototype: EncodedAudioChunk;
|
||||
new(init: EncodedAudioChunkInit): EncodedAudioChunk;
|
||||
};
|
||||
|
||||
interface EncodedVideoChunk {
|
||||
readonly byteLength: number;
|
||||
readonly duration: number | null;
|
||||
readonly timestamp: number;
|
||||
readonly type: EncodedVideoChunkType;
|
||||
copyTo(destination: AllowSharedBufferSource): void;
|
||||
}
|
||||
|
||||
declare var EncodedVideoChunk: {
|
||||
prototype: EncodedVideoChunk;
|
||||
new(init: EncodedVideoChunkInit): EncodedVideoChunk;
|
||||
};
|
||||
|
||||
/** Available only in secure contexts. */
|
||||
interface ImageDecoder {
|
||||
readonly complete: boolean;
|
||||
readonly completed: Promise<void>;
|
||||
readonly tracks: ImageTrackList;
|
||||
readonly type: string;
|
||||
close(): void;
|
||||
decode(options?: ImageDecodeOptions): Promise<ImageDecodeResult>;
|
||||
reset(): void;
|
||||
}
|
||||
|
||||
declare var ImageDecoder: {
|
||||
prototype: ImageDecoder;
|
||||
new(init: ImageDecoderInit): ImageDecoder;
|
||||
isTypeSupported(type: string): Promise<boolean>;
|
||||
};
|
||||
|
||||
interface ImageTrack {
|
||||
readonly animated: boolean;
|
||||
readonly frameCount: number;
|
||||
readonly repetitionCount: number;
|
||||
selected: boolean;
|
||||
}
|
||||
|
||||
declare var ImageTrack: {
|
||||
prototype: ImageTrack;
|
||||
new(): ImageTrack;
|
||||
};
|
||||
|
||||
interface ImageTrackList {
|
||||
readonly length: number;
|
||||
readonly ready: Promise<void>;
|
||||
readonly selectedIndex: number;
|
||||
readonly selectedTrack: ImageTrack | null;
|
||||
[index: number]: ImageTrack;
|
||||
}
|
||||
|
||||
declare var ImageTrackList: {
|
||||
prototype: ImageTrackList;
|
||||
new(): ImageTrackList;
|
||||
};
|
||||
|
||||
interface VideoColorSpace {
|
||||
readonly fullRange: boolean | null;
|
||||
readonly matrix: VideoMatrixCoefficients | null;
|
||||
readonly primaries: VideoColorPrimaries | null;
|
||||
readonly transfer: VideoTransferCharacteristics | null;
|
||||
toJSON(): VideoColorSpaceInit;
|
||||
}
|
||||
|
||||
declare var VideoColorSpace: {
|
||||
prototype: VideoColorSpace;
|
||||
new(init?: VideoColorSpaceInit): VideoColorSpace;
|
||||
};
|
||||
|
||||
interface VideoDecoderEventMap {
|
||||
"dequeue": Event;
|
||||
}
|
||||
|
||||
/** Available only in secure contexts. */
|
||||
interface VideoDecoder {
|
||||
readonly decodeQueueSize: number;
|
||||
readonly state: CodecState;
|
||||
ondequeue: ((this: VideoDecoder, ev: Event) => any) | null;
|
||||
close(): void;
|
||||
configure(config: VideoDecoderConfig): void;
|
||||
decode(chunk: EncodedVideoChunk): void;
|
||||
flush(): Promise<void>;
|
||||
reset(): void;
|
||||
addEventListener<K extends keyof VideoDecoderEventMap>(
|
||||
type: K,
|
||||
listener: (this: VideoDecoder, ev: VideoDecoderEventMap[K]) => any,
|
||||
options?: boolean | AddEventListenerOptions,
|
||||
): void;
|
||||
addEventListener(
|
||||
type: string,
|
||||
listener: EventListenerOrEventListenerObject,
|
||||
options?: boolean | AddEventListenerOptions,
|
||||
): void;
|
||||
removeEventListener<K extends keyof VideoDecoderEventMap>(
|
||||
type: K,
|
||||
listener: (this: VideoDecoder, ev: VideoDecoderEventMap[K]) => any,
|
||||
options?: boolean | EventListenerOptions,
|
||||
): void;
|
||||
removeEventListener(
|
||||
type: string,
|
||||
listener: EventListenerOrEventListenerObject,
|
||||
options?: boolean | EventListenerOptions,
|
||||
): void;
|
||||
}
|
||||
|
||||
declare var VideoDecoder: {
|
||||
prototype: VideoDecoder;
|
||||
new(init: VideoDecoderInit): VideoDecoder;
|
||||
isConfigSupported(config: VideoDecoderConfig): Promise<VideoDecoderSupport>;
|
||||
};
|
||||
|
||||
interface VideoEncoderEventMap {
|
||||
"dequeue": Event;
|
||||
}
|
||||
|
||||
/** Available only in secure contexts. */
|
||||
interface VideoEncoder {
|
||||
readonly encodeQueueSize: number;
|
||||
readonly state: CodecState;
|
||||
close(): void;
|
||||
ondequeue: ((this: VideoEncoder, ev: Event) => any) | null;
|
||||
configure(config: VideoEncoderConfig): void;
|
||||
encode(frame: VideoFrame, options?: VideoEncoderEncodeOptions): void;
|
||||
flush(): Promise<void>;
|
||||
reset(): void;
|
||||
addEventListener<K extends keyof VideoEncoderEventMap>(
|
||||
type: K,
|
||||
listener: (this: VideoEncoder, ev: VideoEncoderEventMap[K]) => any,
|
||||
options?: boolean | AddEventListenerOptions,
|
||||
): void;
|
||||
addEventListener(
|
||||
type: string,
|
||||
listener: EventListenerOrEventListenerObject,
|
||||
options?: boolean | AddEventListenerOptions,
|
||||
): void;
|
||||
removeEventListener<K extends keyof VideoEncoderEventMap>(
|
||||
type: K,
|
||||
listener: (this: VideoEncoder, ev: VideoEncoderEventMap[K]) => any,
|
||||
options?: boolean | EventListenerOptions,
|
||||
): void;
|
||||
removeEventListener(
|
||||
type: string,
|
||||
listener: EventListenerOrEventListenerObject,
|
||||
options?: boolean | EventListenerOptions,
|
||||
): void;
|
||||
}
|
||||
|
||||
declare var VideoEncoder: {
|
||||
prototype: VideoEncoder;
|
||||
new(init: VideoEncoderInit): VideoEncoder;
|
||||
isConfigSupported(config: VideoEncoderConfig): Promise<VideoEncoderSupport>;
|
||||
};
|
||||
|
||||
interface VideoFrame {
|
||||
readonly codedHeight: number;
|
||||
readonly codedRect: DOMRectReadOnly | null;
|
||||
readonly codedWidth: number;
|
||||
readonly colorSpace: VideoColorSpace;
|
||||
readonly displayHeight: number;
|
||||
readonly displayWidth: number;
|
||||
readonly duration: number | null;
|
||||
readonly format: VideoPixelFormat | null;
|
||||
readonly timestamp: number;
|
||||
readonly visibleRect: DOMRectReadOnly | null;
|
||||
allocationSize(options?: VideoFrameCopyToOptions): number;
|
||||
clone(): VideoFrame;
|
||||
close(): void;
|
||||
copyTo(destination: AllowSharedBufferSource, options?: VideoFrameCopyToOptions): Promise<PlaneLayout[]>;
|
||||
}
|
||||
|
||||
declare var VideoFrame: {
|
||||
prototype: VideoFrame;
|
||||
new(source: CanvasImageSource, init?: VideoFrameInit): VideoFrame;
|
||||
new(data: AllowSharedBufferSource, init: VideoFrameBufferInit): VideoFrame;
|
||||
};
|
||||
|
||||
interface AudioDataOutputCallback {
|
||||
(output: AudioData): void;
|
||||
}
|
||||
|
||||
interface EncodedAudioChunkOutputCallback {
|
||||
(output: EncodedAudioChunk, metadata: EncodedAudioChunkMetadata): void;
|
||||
}
|
||||
|
||||
interface EncodedVideoChunkOutputCallback {
|
||||
(chunk: EncodedVideoChunk, metadata: EncodedVideoChunkMetadata): void;
|
||||
}
|
||||
|
||||
interface VideoFrameOutputCallback {
|
||||
(output: VideoFrame): void;
|
||||
}
|
||||
|
||||
interface WebCodecsErrorCallback {
|
||||
(error: DOMException): void;
|
||||
}
|
||||
|
||||
// type AllowSharedBufferSource = ArrayBuffer | ArrayBufferView;
|
||||
// type BitrateMode = "constant" | "variable";
|
||||
type ImageBufferSource = ArrayBuffer | ArrayBufferView | ReadableStream;
|
||||
// type AlphaOption = "discard" | "keep";
|
||||
// type AudioSampleFormat = "f32" | "f32-planar" | "s16" | "s16-planar" | "s32" | "s32-planar" | "u8" | "u8-planar";
|
||||
// type AvcBitstreamFormat = "annexb" | "avc";
|
||||
// type CodecState = "closed" | "configured" | "unconfigured";
|
||||
// type EncodedAudioChunkType = "delta" | "key";
|
||||
// type EncodedVideoChunkType = "delta" | "key";
|
||||
type HardwarePreference = "no-preference" | "prefer-hardware" | "prefer-software";
|
||||
// type LatencyMode = "quality" | "realtime";
|
||||
// type VideoColorPrimaries = "bt470bg" | "bt709" | "smpte170m";
|
||||
// type VideoMatrixCoefficients = "bt470bg" | "bt709" | "rgb" | "smpte170m";
|
||||
// type VideoPixelFormat = "BGRA" | "BGRX" | "I420" | "I420A" | "I422" | "I444" | "NV12" | "RGBA" | "RGBX";
|
||||
// type VideoTransferCharacteristics = "bt709" | "iec61966-2-1" | "smpte170m";
|
21
node_modules/@types/emscripten/LICENSE
generated
vendored
Normal file
21
node_modules/@types/emscripten/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
15
node_modules/@types/emscripten/README.md
generated
vendored
Normal file
15
node_modules/@types/emscripten/README.md
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# Installation
|
||||
> `npm install --save @types/emscripten`
|
||||
|
||||
# Summary
|
||||
This package contains type definitions for emscripten (https://emscripten.org).
|
||||
|
||||
# Details
|
||||
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/emscripten.
|
||||
|
||||
### Additional Details
|
||||
* Last updated: Tue, 28 May 2024 20:07:23 GMT
|
||||
* Dependencies: none
|
||||
|
||||
# Credits
|
||||
These definitions were written by [Kensuke Matsuzaki](https://github.com/zakki), [Periklis Tsirakidis](https://github.com/periklis), [Bumsik Kim](https://github.com/kbumsik), and [Louis DeScioli](https://github.com/lourd).
|
451
node_modules/@types/emscripten/index.d.ts
generated
vendored
Normal file
451
node_modules/@types/emscripten/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,451 @@
|
||||
/** Other WebAssembly declarations, for compatibility with older versions of Typescript */
|
||||
declare namespace WebAssembly {
|
||||
interface Module {}
|
||||
}
|
||||
|
||||
declare namespace Emscripten {
|
||||
interface FileSystemType {
|
||||
mount(mount: FS.Mount): FS.FSNode;
|
||||
syncfs(mount: FS.Mount, populate: () => unknown, done: (err?: number | null) => unknown): void;
|
||||
}
|
||||
type EnvironmentType = "WEB" | "NODE" | "SHELL" | "WORKER";
|
||||
|
||||
type JSType = "number" | "string" | "array" | "boolean";
|
||||
type TypeCompatibleWithC = number | string | any[] | boolean;
|
||||
|
||||
type CIntType = "i8" | "i16" | "i32" | "i64";
|
||||
type CFloatType = "float" | "double";
|
||||
type CPointerType = "i8*" | "i16*" | "i32*" | "i64*" | "float*" | "double*" | "*";
|
||||
type CType = CIntType | CFloatType | CPointerType;
|
||||
|
||||
interface CCallOpts {
|
||||
async?: boolean | undefined;
|
||||
}
|
||||
}
|
||||
|
||||
interface EmscriptenModule {
|
||||
print(str: string): void;
|
||||
printErr(str: string): void;
|
||||
arguments: string[];
|
||||
environment: Emscripten.EnvironmentType;
|
||||
preInit: Array<{ (): void }>;
|
||||
preRun: Array<{ (): void }>;
|
||||
postRun: Array<{ (): void }>;
|
||||
onAbort: { (what: any): void };
|
||||
onRuntimeInitialized: { (): void };
|
||||
preinitializedWebGLContext: WebGLRenderingContext;
|
||||
noInitialRun: boolean;
|
||||
noExitRuntime: boolean;
|
||||
logReadFiles: boolean;
|
||||
filePackagePrefixURL: string;
|
||||
wasmBinary: ArrayBuffer;
|
||||
|
||||
destroy(object: object): void;
|
||||
getPreloadedPackage(remotePackageName: string, remotePackageSize: number): ArrayBuffer;
|
||||
instantiateWasm(
|
||||
imports: WebAssembly.Imports,
|
||||
successCallback: (module: WebAssembly.Instance) => void,
|
||||
): WebAssembly.Exports | undefined;
|
||||
locateFile(url: string, scriptDirectory: string): string;
|
||||
onCustomMessage(event: MessageEvent): void;
|
||||
|
||||
// USE_TYPED_ARRAYS == 1
|
||||
HEAP: Int32Array;
|
||||
IHEAP: Int32Array;
|
||||
FHEAP: Float64Array;
|
||||
|
||||
// USE_TYPED_ARRAYS == 2
|
||||
HEAP8: Int8Array;
|
||||
HEAP16: Int16Array;
|
||||
HEAP32: Int32Array;
|
||||
HEAPU8: Uint8Array;
|
||||
HEAPU16: Uint16Array;
|
||||
HEAPU32: Uint32Array;
|
||||
HEAPF32: Float32Array;
|
||||
HEAPF64: Float64Array;
|
||||
HEAP64: BigInt64Array;
|
||||
HEAPU64: BigUint64Array;
|
||||
|
||||
TOTAL_STACK: number;
|
||||
TOTAL_MEMORY: number;
|
||||
FAST_MEMORY: number;
|
||||
|
||||
addOnPreRun(cb: () => any): void;
|
||||
addOnInit(cb: () => any): void;
|
||||
addOnPreMain(cb: () => any): void;
|
||||
addOnExit(cb: () => any): void;
|
||||
addOnPostRun(cb: () => any): void;
|
||||
|
||||
preloadedImages: any;
|
||||
preloadedAudios: any;
|
||||
|
||||
_malloc(size: number): number;
|
||||
_free(ptr: number): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory function is generated when setting the `MODULARIZE` build option
|
||||
* to `1` in your Emscripten build. It return a Promise that resolves to an
|
||||
* initialized, ready-to-call `EmscriptenModule` instance.
|
||||
*
|
||||
* By default, the factory function will be named `Module`. It's recommended to
|
||||
* use the `EXPORT_ES6` option, in which the factory function will be the
|
||||
* default export. If used without `EXPORT_ES6`, the factory function will be a
|
||||
* global variable. You can rename the variable using the `EXPORT_NAME` build
|
||||
* option. It's left to you to declare any global variables as needed in your
|
||||
* application's types.
|
||||
* @param moduleOverrides Default properties for the initialized module.
|
||||
*/
|
||||
type EmscriptenModuleFactory<T extends EmscriptenModule = EmscriptenModule> = (
|
||||
moduleOverrides?: Partial<T>,
|
||||
) => Promise<T>;
|
||||
|
||||
declare namespace FS {
|
||||
interface Lookup {
|
||||
path: string;
|
||||
node: FSNode;
|
||||
}
|
||||
|
||||
interface Analyze {
|
||||
isRoot: boolean;
|
||||
exists: boolean;
|
||||
error: Error;
|
||||
name: string;
|
||||
path: Lookup["path"];
|
||||
object: Lookup["node"];
|
||||
parentExists: boolean;
|
||||
parentPath: Lookup["path"];
|
||||
parentObject: Lookup["node"];
|
||||
}
|
||||
|
||||
interface Mount {
|
||||
type: Emscripten.FileSystemType;
|
||||
opts: object;
|
||||
mountpoint: string;
|
||||
mounts: Mount[];
|
||||
root: FSNode;
|
||||
}
|
||||
|
||||
class FSStream {
|
||||
constructor();
|
||||
object: FSNode;
|
||||
readonly isRead: boolean;
|
||||
readonly isWrite: boolean;
|
||||
readonly isAppend: boolean;
|
||||
flags: number;
|
||||
position: number;
|
||||
fd?: number;
|
||||
nfd?: number;
|
||||
}
|
||||
|
||||
interface StreamOps {
|
||||
open(stream: FSStream): void;
|
||||
close(stream: FSStream): void;
|
||||
read(stream: FSStream, buffer: Uint8Array, offset: number, length: number, position: number): number;
|
||||
write(stream: FSStream, buffer: Uint8Array, offset: number, length: number, position: number): number;
|
||||
llseek(stream: FSStream, offset: number, whence: number): number;
|
||||
}
|
||||
|
||||
class FSNode {
|
||||
parent: FSNode;
|
||||
mount: Mount;
|
||||
mounted?: Mount;
|
||||
id: number;
|
||||
name: string;
|
||||
mode: number;
|
||||
rdev: number;
|
||||
readMode: number;
|
||||
writeMode: number;
|
||||
constructor(parent: FSNode, name: string, mode: number, rdev: number);
|
||||
read: boolean;
|
||||
write: boolean;
|
||||
readonly isFolder: boolean;
|
||||
readonly isDevice: boolean;
|
||||
}
|
||||
|
||||
interface NodeOps {
|
||||
getattr(node: FSNode): Stats;
|
||||
setattr(node: FSNode, attr: Stats): void;
|
||||
lookup(parent: FSNode, name: string): FSNode;
|
||||
mknod(parent: FSNode, name: string, mode: number, dev: unknown): FSNode;
|
||||
rename(oldNode: FSNode, newDir: FSNode, newName: string): void;
|
||||
unlink(parent: FSNode, name: string): void;
|
||||
rmdir(parent: FSNode, name: string): void;
|
||||
readdir(node: FSNode): string[];
|
||||
symlink(parent: FSNode, newName: string, oldPath: string): void;
|
||||
readlink(node: FSNode): string;
|
||||
}
|
||||
|
||||
interface Stats {
|
||||
dev: number;
|
||||
ino: number;
|
||||
mode: number;
|
||||
nlink: number;
|
||||
uid: number;
|
||||
gid: number;
|
||||
rdev: number;
|
||||
size: number;
|
||||
blksize: number;
|
||||
blocks: number;
|
||||
atime: Date;
|
||||
mtime: Date;
|
||||
ctime: Date;
|
||||
timestamp?: number;
|
||||
}
|
||||
|
||||
class ErrnoError extends Error {
|
||||
name: "ErronoError";
|
||||
errno: number;
|
||||
code: string;
|
||||
constructor(errno: number);
|
||||
}
|
||||
|
||||
let ignorePermissions: boolean;
|
||||
let trackingDelegate: {
|
||||
onOpenFile(path: string, trackingFlags: number): unknown;
|
||||
onCloseFile(path: string): unknown;
|
||||
onSeekFile(path: string, position: number, whence: number): unknown;
|
||||
onReadFile(path: string, bytesRead: number): unknown;
|
||||
onWriteToFile(path: string, bytesWritten: number): unknown;
|
||||
onMakeDirectory(path: string, mode: number): unknown;
|
||||
onMakeSymlink(oldpath: string, newpath: string): unknown;
|
||||
willMovePath(old_path: string, new_path: string): unknown;
|
||||
onMovePath(old_path: string, new_path: string): unknown;
|
||||
willDeletePath(path: string): unknown;
|
||||
onDeletePath(path: string): unknown;
|
||||
};
|
||||
let tracking: any;
|
||||
let genericErrors: Record<number, ErrnoError>;
|
||||
|
||||
//
|
||||
// paths
|
||||
//
|
||||
function lookupPath(
|
||||
path: string,
|
||||
opts: Partial<{
|
||||
follow_mount: boolean;
|
||||
/**
|
||||
* by default, lookupPath will not follow a symlink if it is the final path component.
|
||||
* setting opts.follow = true will override this behavior.
|
||||
*/
|
||||
follow: boolean;
|
||||
recurse_count: number;
|
||||
parent: boolean;
|
||||
}>,
|
||||
): Lookup;
|
||||
function getPath(node: FSNode): string;
|
||||
function analyzePath(path: string, dontResolveLastLink?: boolean): Analyze;
|
||||
|
||||
//
|
||||
// nodes
|
||||
//
|
||||
function isFile(mode: number): boolean;
|
||||
function isDir(mode: number): boolean;
|
||||
function isLink(mode: number): boolean;
|
||||
function isChrdev(mode: number): boolean;
|
||||
function isBlkdev(mode: number): boolean;
|
||||
function isFIFO(mode: number): boolean;
|
||||
function isSocket(mode: number): boolean;
|
||||
|
||||
//
|
||||
// devices
|
||||
//
|
||||
function major(dev: number): number;
|
||||
function minor(dev: number): number;
|
||||
function makedev(ma: number, mi: number): number;
|
||||
function registerDevice(dev: number, ops: Partial<StreamOps>): void;
|
||||
function getDevice(dev: number): { stream_ops: StreamOps };
|
||||
|
||||
//
|
||||
// core
|
||||
//
|
||||
function getMounts(mount: Mount): Mount[];
|
||||
function syncfs(populate: boolean, callback: (e: any) => any): void;
|
||||
function syncfs(callback: (e: any) => any, populate?: boolean): void;
|
||||
function mount(type: Emscripten.FileSystemType, opts: any, mountpoint: string): any;
|
||||
function unmount(mountpoint: string): void;
|
||||
|
||||
function mkdir(path: string, mode?: number): FSNode;
|
||||
function mkdev(path: string, mode?: number, dev?: number): FSNode;
|
||||
function symlink(oldpath: string, newpath: string): FSNode;
|
||||
function rename(old_path: string, new_path: string): void;
|
||||
function rmdir(path: string): void;
|
||||
function readdir(path: string): string[];
|
||||
function unlink(path: string): void;
|
||||
function readlink(path: string): string;
|
||||
function stat(path: string, dontFollow?: boolean): Stats;
|
||||
function lstat(path: string): Stats;
|
||||
function chmod(path: string, mode: number, dontFollow?: boolean): void;
|
||||
function lchmod(path: string, mode: number): void;
|
||||
function fchmod(fd: number, mode: number): void;
|
||||
function chown(path: string, uid: number, gid: number, dontFollow?: boolean): void;
|
||||
function lchown(path: string, uid: number, gid: number): void;
|
||||
function fchown(fd: number, uid: number, gid: number): void;
|
||||
function truncate(path: string, len: number): void;
|
||||
function ftruncate(fd: number, len: number): void;
|
||||
function utime(path: string, atime: number, mtime: number): void;
|
||||
function open(path: string, flags: string, mode?: number, fd_start?: number, fd_end?: number): FSStream;
|
||||
function close(stream: FSStream): void;
|
||||
function llseek(stream: FSStream, offset: number, whence: number): number;
|
||||
function read(stream: FSStream, buffer: ArrayBufferView, offset: number, length: number, position?: number): number;
|
||||
function write(
|
||||
stream: FSStream,
|
||||
buffer: ArrayBufferView,
|
||||
offset: number,
|
||||
length: number,
|
||||
position?: number,
|
||||
canOwn?: boolean,
|
||||
): number;
|
||||
function allocate(stream: FSStream, offset: number, length: number): void;
|
||||
function mmap(
|
||||
stream: FSStream,
|
||||
buffer: ArrayBufferView,
|
||||
offset: number,
|
||||
length: number,
|
||||
position: number,
|
||||
prot: number,
|
||||
flags: number,
|
||||
): {
|
||||
allocated: boolean;
|
||||
ptr: number;
|
||||
};
|
||||
function ioctl(stream: FSStream, cmd: any, arg: any): any;
|
||||
function readFile(path: string, opts: { encoding: "binary"; flags?: string | undefined }): Uint8Array;
|
||||
function readFile(path: string, opts: { encoding: "utf8"; flags?: string | undefined }): string;
|
||||
function readFile(path: string, opts?: { flags?: string | undefined }): Uint8Array;
|
||||
function writeFile(path: string, data: string | ArrayBufferView, opts?: { flags?: string | undefined }): void;
|
||||
|
||||
//
|
||||
// module-level FS code
|
||||
//
|
||||
function cwd(): string;
|
||||
function chdir(path: string): void;
|
||||
function init(
|
||||
input: null | (() => number | null),
|
||||
output: null | ((c: number) => any),
|
||||
error: null | ((c: number) => any),
|
||||
): void;
|
||||
|
||||
function createLazyFile(
|
||||
parent: string | FSNode,
|
||||
name: string,
|
||||
url: string,
|
||||
canRead: boolean,
|
||||
canWrite: boolean,
|
||||
): FSNode;
|
||||
function createPreloadedFile(
|
||||
parent: string | FSNode,
|
||||
name: string,
|
||||
url: string,
|
||||
canRead: boolean,
|
||||
canWrite: boolean,
|
||||
onload?: () => void,
|
||||
onerror?: () => void,
|
||||
dontCreateFile?: boolean,
|
||||
canOwn?: boolean,
|
||||
): void;
|
||||
function createDataFile(
|
||||
parent: string | FSNode,
|
||||
name: string,
|
||||
data: ArrayBufferView,
|
||||
canRead: boolean,
|
||||
canWrite: boolean,
|
||||
canOwn: boolean,
|
||||
): FSNode;
|
||||
}
|
||||
|
||||
declare var MEMFS: Emscripten.FileSystemType;
|
||||
declare var NODEFS: Emscripten.FileSystemType;
|
||||
declare var IDBFS: Emscripten.FileSystemType;
|
||||
|
||||
// https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html
|
||||
type StringToType<R extends any> = R extends Emscripten.JSType ? {
|
||||
number: number;
|
||||
string: string;
|
||||
array: number[] | string[] | boolean[] | Uint8Array | Int8Array;
|
||||
boolean: boolean;
|
||||
null: null;
|
||||
}[R]
|
||||
: never;
|
||||
|
||||
type ArgsToType<T extends Array<Emscripten.JSType | null>> = Extract<
|
||||
{
|
||||
[P in keyof T]: StringToType<T[P]>;
|
||||
},
|
||||
any[]
|
||||
>;
|
||||
|
||||
type ReturnToType<R extends Emscripten.JSType | null> = R extends null ? null : StringToType<Exclude<R, null>>;
|
||||
|
||||
// Below runtime function/variable declarations are exportable by
|
||||
// -s EXTRA_EXPORTED_RUNTIME_METHODS. You can extend or merge
|
||||
// EmscriptenModule interface to add runtime functions.
|
||||
//
|
||||
// For example, by using -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall']"
|
||||
// You can access ccall() via Module["ccall"]. In this case, you should
|
||||
// extend EmscriptenModule to pass the compiler check like the following:
|
||||
//
|
||||
// interface YourOwnEmscriptenModule extends EmscriptenModule {
|
||||
// ccall: typeof ccall;
|
||||
// }
|
||||
//
|
||||
// See: https://emscripten.org/docs/getting_started/FAQ.html#why-do-i-get-typeerror-module-something-is-not-a-function
|
||||
|
||||
declare function cwrap<I extends Array<Emscripten.JSType | null> | [], R extends Emscripten.JSType | null>(
|
||||
ident: string,
|
||||
returnType: R,
|
||||
argTypes: I,
|
||||
opts?: Emscripten.CCallOpts,
|
||||
): (...arg: ArgsToType<I>) => ReturnToType<R>;
|
||||
|
||||
declare function ccall<I extends Array<Emscripten.JSType | null> | [], R extends Emscripten.JSType | null>(
|
||||
ident: string,
|
||||
returnType: R,
|
||||
argTypes: I,
|
||||
args: ArgsToType<I>,
|
||||
opts?: Emscripten.CCallOpts,
|
||||
): ReturnToType<R>;
|
||||
|
||||
declare function setValue(ptr: number, value: any, type: Emscripten.CType, noSafe?: boolean): void;
|
||||
declare function getValue(ptr: number, type: Emscripten.CType, noSafe?: boolean): number;
|
||||
|
||||
declare function allocate(
|
||||
slab: number[] | ArrayBufferView | number,
|
||||
types: Emscripten.CType | Emscripten.CType[],
|
||||
allocator: number,
|
||||
ptr?: number,
|
||||
): number;
|
||||
|
||||
declare function stackAlloc(size: number): number;
|
||||
declare function stackSave(): number;
|
||||
declare function stackRestore(ptr: number): void;
|
||||
|
||||
declare function UTF8ToString(ptr: number, maxBytesToRead?: number): string;
|
||||
declare function stringToUTF8(str: string, outPtr: number, maxBytesToRead?: number): void;
|
||||
declare function lengthBytesUTF8(str: string): number;
|
||||
declare function allocateUTF8(str: string): number;
|
||||
declare function allocateUTF8OnStack(str: string): number;
|
||||
declare function UTF16ToString(ptr: number): string;
|
||||
declare function stringToUTF16(str: string, outPtr: number, maxBytesToRead?: number): void;
|
||||
declare function lengthBytesUTF16(str: string): number;
|
||||
declare function UTF32ToString(ptr: number): string;
|
||||
declare function stringToUTF32(str: string, outPtr: number, maxBytesToRead?: number): void;
|
||||
declare function lengthBytesUTF32(str: string): number;
|
||||
|
||||
declare function intArrayFromString(stringy: string, dontAddNull?: boolean, length?: number): number[];
|
||||
declare function intArrayToString(array: number[]): string;
|
||||
declare function writeStringToMemory(str: string, buffer: number, dontAddNull: boolean): void;
|
||||
declare function writeArrayToMemory(array: number[], buffer: number): void;
|
||||
declare function writeAsciiToMemory(str: string, buffer: number, dontAddNull: boolean): void;
|
||||
|
||||
declare function addRunDependency(id: any): void;
|
||||
declare function removeRunDependency(id: any): void;
|
||||
|
||||
declare function addFunction(func: (...args: any[]) => any, signature?: string): number;
|
||||
declare function removeFunction(funcPtr: number): void;
|
||||
|
||||
declare var ALLOC_NORMAL: number;
|
||||
declare var ALLOC_STACK: number;
|
||||
declare var ALLOC_STATIC: number;
|
||||
declare var ALLOC_DYNAMIC: number;
|
||||
declare var ALLOC_NONE: number;
|
40
node_modules/@types/emscripten/package.json
generated
vendored
Normal file
40
node_modules/@types/emscripten/package.json
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "@types/emscripten",
|
||||
"version": "1.39.13",
|
||||
"description": "TypeScript definitions for emscripten",
|
||||
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/emscripten",
|
||||
"license": "MIT",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Kensuke Matsuzaki",
|
||||
"githubUsername": "zakki",
|
||||
"url": "https://github.com/zakki"
|
||||
},
|
||||
{
|
||||
"name": "Periklis Tsirakidis",
|
||||
"githubUsername": "periklis",
|
||||
"url": "https://github.com/periklis"
|
||||
},
|
||||
{
|
||||
"name": "Bumsik Kim",
|
||||
"githubUsername": "kbumsik",
|
||||
"url": "https://github.com/kbumsik"
|
||||
},
|
||||
{
|
||||
"name": "Louis DeScioli",
|
||||
"githubUsername": "lourd",
|
||||
"url": "https://github.com/lourd"
|
||||
}
|
||||
],
|
||||
"main": "",
|
||||
"types": "index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
|
||||
"directory": "types/emscripten"
|
||||
},
|
||||
"scripts": {},
|
||||
"dependencies": {},
|
||||
"typesPublisherContentHash": "e4c38466f07759bfefe22fd073222d18f79b78112fc989c972f3e86c81b49800",
|
||||
"typeScriptVersion": "4.7"
|
||||
}
|
21
node_modules/barcode-detector/LICENSE
generated
vendored
Normal file
21
node_modules/barcode-detector/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Ze-Zheng Wu
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
263
node_modules/barcode-detector/README.md
generated
vendored
Normal file
263
node_modules/barcode-detector/README.md
generated
vendored
Normal file
@ -0,0 +1,263 @@
|
||||
# barcode-detector
|
||||
|
||||
[](https://www.npmjs.com/package/barcode-detector/v/latest) [](https://www.npmjs.com/package/barcode-detector/v/latest) [](https://cdn.jsdelivr.net/npm/barcode-detector@latest/)
|
||||
|
||||
A [Barcode Detection API](https://wicg.github.io/shape-detection-api/#barcode-detection-api) polyfill that uses [ZXing-C++ WebAssembly](https://github.com/Sec-ant/zxing-wasm) under the hood.
|
||||
|
||||
Supported barcode formats: `aztec`, `code_128`, `code_39`, `code_93`, `codabar`, `databar`, `databar_expanded`, `data_matrix`, `dx_film_edge`, `ean_13`, `ean_8`, `itf`, `maxi_code` (only generated ones, and no position info), `micro_qr_code`, `pdf417`, `qr_code`, `rm_qr_code`, `upc_a`, `upc_e`, `linear_codes` and `matrix_codes` (for convenience).
|
||||
|
||||
## Install
|
||||
|
||||
To install, run the following command:
|
||||
|
||||
```bash
|
||||
npm i barcode-detector
|
||||
```
|
||||
|
||||
## Recommended Usage with Node + ESM
|
||||
|
||||
This package can be imported in three different ways:
|
||||
|
||||
### Pure Module
|
||||
|
||||
```ts
|
||||
import { BarcodeDetector } from "barcode-detector/pure";
|
||||
```
|
||||
|
||||
To avoid potential namespace collisions, you can also rename the export:
|
||||
|
||||
```ts
|
||||
import { BarcodeDetector as BarcodeDetectorPolyfill } from "barcode-detector/pure";
|
||||
```
|
||||
|
||||
This approach is beneficial when you want to use a package to detect barcodes without polluting `globalThis`, or when your runtime already provides an implementation of the Barcode Detection API, but you still want this package to function.
|
||||
|
||||
### Side Effects
|
||||
|
||||
```ts
|
||||
import "barcode-detector/side-effects";
|
||||
```
|
||||
|
||||
This approach is beneficial when you need a drop-in polyfill. If there's already an implementation of Barcode Detection API on `globalThis`, this won't take effect (type declarations will, as we cannot optionally declare types). In such cases, please use the [pure module](#pure-module) instead.
|
||||
|
||||
### Both
|
||||
|
||||
```ts
|
||||
import { BarcodeDetector } from "barcode-detector";
|
||||
```
|
||||
|
||||
This approach combines the [pure module](#pure-module) and [side effects](#side-effects).
|
||||
|
||||
## Recommended Usage in Modern Browsers
|
||||
|
||||
For [modern browsers that support ES modules](https://caniuse.com/es6-module), this package can be imported via the `<script type="module">` tags:
|
||||
|
||||
1. Include side effects:
|
||||
|
||||
```html
|
||||
<!-- register -->
|
||||
<script
|
||||
type="module"
|
||||
src="https://fastly.jsdelivr.net/npm/barcode-detector@2/dist/es/side-effects.min.js"
|
||||
></script>
|
||||
|
||||
<!-- use -->
|
||||
<script type="module">
|
||||
const barcodeDetector = new BarcodeDetector();
|
||||
</script>
|
||||
```
|
||||
|
||||
2. Script scoped access:
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { BarcodeDetector } from "https://fastly.jsdelivr.net/npm/barcode-detector@2/dist/es/pure.min.js";
|
||||
const barcodeDetector = new BarcodeDetector();
|
||||
</script>
|
||||
```
|
||||
|
||||
3. With import maps:
|
||||
|
||||
```html
|
||||
<!-- import map -->
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"barcode-detector/pure": "https://fastly.jsdelivr.net/npm/barcode-detector@2/dist/es/pure.min.js"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- script scoped access -->
|
||||
<script type="module">
|
||||
import { BarcodeDetector } from "barcode-detector/pure";
|
||||
const barcodeDetector = new BarcodeDetector();
|
||||
</script>
|
||||
```
|
||||
|
||||
## Usage with Legacy Compatibility
|
||||
|
||||
Starting from v1.2, this package supports IIFE and CJS build outputs for use cases that require legacy compatibility.
|
||||
|
||||
### IIFE
|
||||
|
||||
For legacy browsers that lack support for module type `<script>` tags, or for userscripts, IIFE is the preferred choice. Upon executing the IIFE script, a variable named `BarcodeDetectionAPI` will be registered in the global.
|
||||
|
||||
```html
|
||||
<!--
|
||||
IIFE pure.js registers:
|
||||
window.BarcodeDetectionAPI.BarcodeDetector
|
||||
window.BarcodeDetectionAPI.setZXingModuleOverrides
|
||||
-->
|
||||
<script src="https://fastly.jsdelivr.net/npm/barcode-detector@2/dist/iife/pure.min.js"></script>
|
||||
|
||||
<!--
|
||||
IIFE side-effects.js registers:
|
||||
window.BarcodeDetector
|
||||
window.BarcodeDetectionAPI.setZXingModuleOverrides
|
||||
-->
|
||||
<script src="https://fastly.jsdelivr.net/npm/barcode-detector@2/dist/iife/side-effects.min.js"></script>
|
||||
|
||||
<!--
|
||||
IIFE index.js registers:
|
||||
window.BarcodeDetector
|
||||
window.BarcodeDetectionAPI.BarcodeDetector
|
||||
window.BarcodeDetectionAPI.setZXingModuleOverrides
|
||||
-->
|
||||
<script src="https://fastly.jsdelivr.net/npm/barcode-detector@2/dist/iife/index.min.js"></script>
|
||||
```
|
||||
|
||||
### CJS
|
||||
|
||||
This package can also be consumed as a commonjs package:
|
||||
|
||||
1. Vanilla Javascript:
|
||||
|
||||
```js
|
||||
// src/index.js
|
||||
const { BarcodeDetector } = require("barcode-detector/pure");
|
||||
```
|
||||
|
||||
2. With Typescript:
|
||||
|
||||
```ts
|
||||
// src/index.ts
|
||||
import { BarcodeDetector } from "barcode-detector/pure";
|
||||
```
|
||||
|
||||
`tsconfig.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "Node",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
```
|
||||
|
||||
## `setZXingModuleOverrides`
|
||||
|
||||
In addition to `BarcodeDetector`, this package exports another function called `setZXingModuleOverrides`.
|
||||
|
||||
This package employs [zxing-wasm](https://github.com/Sec-ant/zxing-wasm) to enable the core barcode reading functionality. As a result, a `.wasm` binary file is fetched at runtime. The default fetch path for this binary file is:
|
||||
|
||||
```
|
||||
https://fastly.jsdelivr.net/npm/zxing-wasm@<version>/dist/reader/zxing_reader.wasm
|
||||
```
|
||||
|
||||
The `setZXingModuleOverrides` function allows you to govern where the `.wasm` binary is served from, thereby enabling offline use of the package, use within a local network, or within a site having strict [CSP](https://developer.mozilla.org/docs/Web/HTTP/CSP) rules.
|
||||
|
||||
For instance, should you want to inline this `.wasm` file in your build output for offline usage, with the assistance of build tools, you could try:
|
||||
|
||||
```ts
|
||||
// src/index.ts
|
||||
import wasmFile from "../node_modules/zxing-wasm/dist/reader/zxing_reader.wasm?url";
|
||||
|
||||
import {
|
||||
setZXingModuleOverrides,
|
||||
BarcodeDetector,
|
||||
} from "barcode-detector/pure";
|
||||
|
||||
setZXingModuleOverrides({
|
||||
locateFile: (path, prefix) => {
|
||||
if (path.endsWith(".wasm")) {
|
||||
return wasmFile;
|
||||
}
|
||||
return prefix + path;
|
||||
},
|
||||
});
|
||||
|
||||
const barcodeDetector = new BarcodeDetector();
|
||||
|
||||
// detect barcodes
|
||||
// ...
|
||||
```
|
||||
|
||||
Alternatively, the `.wasm` file could be copied to your dist folder to be served from your local server, without incorporating it into the output as an extensive base64 data URL.
|
||||
|
||||
It's noteworthy that you'll always want to choose the correct version of the `.wasm` file, so the APIs exported by it are exactly what the js code expects.
|
||||
|
||||
For more information on how to use this function, you can check [the notes here](https://github.com/Sec-ant/zxing-wasm#notes) and [discussions here](https://github.com/Sec-ant/barcode-detector/issues/18) and [here](https://github.com/gruhn/vue-qrcode-reader/issues/354).
|
||||
|
||||
This function is exported from all the subpaths, including the [side effects](#side-effects).
|
||||
|
||||
## API
|
||||
|
||||
Please check the [spec](https://wicg.github.io/shape-detection-api/#barcode-detection-api), [MDN doc](https://developer.mozilla.org/docs/Web/API/Barcode_Detection_API) and [Chromium implementation](https://github.com/chromium/chromium/tree/main/third_party/blink/renderer/modules/shapedetection) for more information.
|
||||
|
||||
## Lifecycle Events
|
||||
|
||||
The `BarcodeDetector` provided by this package also extends class `EventTarget` and provides 2 lifecycle events: `load` and `error`. You can use `addEventListener` and `removeEventListener` to register and remove callback hooks on these events.
|
||||
|
||||
### `load` Event
|
||||
|
||||
The `load` event, which is a `CustomEvent`, will be dispatched on the successful instantiation of ZXing wasm module. For advanced usage, the instantiated module is passed as the `detail` parameter.
|
||||
|
||||
```ts
|
||||
import { BarcodeDetector } from "barcode-detector/pure";
|
||||
|
||||
const barcodeDetector = new BarcodeDetector();
|
||||
|
||||
barcodeDetector.addEventListener("load", ({ detail }) => {
|
||||
console.log(detail); // zxing wasm module
|
||||
});
|
||||
```
|
||||
|
||||
### `error` Event
|
||||
|
||||
The `error` event, which is a `CustomEvent`, will be dispatched if the instantiation of ZXing wasm module is failed. An error is passed as the `detail` parameter.
|
||||
|
||||
```ts
|
||||
import { BarcodeDetector } from "barcode-detector/pure";
|
||||
|
||||
const barcodeDetector = new BarcodeDetector();
|
||||
|
||||
barcodeDetector.addEventListener("error", ({ detail }) => {
|
||||
console.log(detail); // an error
|
||||
});
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```ts
|
||||
import { BarcodeDetector } from "barcode-detector/pure";
|
||||
|
||||
const barcodeDetector: BarcodeDetector = new BarcodeDetector({
|
||||
formats: ["qr_code"],
|
||||
});
|
||||
|
||||
const imageFile = await fetch(
|
||||
"https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=Hello%20world!",
|
||||
).then((resp) => resp.blob());
|
||||
|
||||
barcodeDetector.detect(imageFile).then(console.log);
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
The source code in this repository, as well as the build output, except for the parts listed below, is licensed under the [MIT license](./LICENSE).
|
||||
|
||||
Test samples and resources are collected from [zxing-cpp/zxing-cpp](https://github.com/zxing-cpp/zxing-cpp), which is licensed under the [Apache-2.0 license](https://raw.githubusercontent.com/zxing-cpp/zxing-cpp/master/LICENSE), and [web-platform-tests/wpt](https://github.com/web-platform-tests/wpt), which is licensed under the [3-Clause BSD license](https://raw.githubusercontent.com/web-platform-tests/wpt/master/LICENSE.md).
|
35
node_modules/barcode-detector/dist/cjs/BarcodeDetector.d.ts
generated
vendored
Normal file
35
node_modules/barcode-detector/dist/cjs/BarcodeDetector.d.ts
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
/// <reference types="dom-webcodecs" />
|
||||
import { type ZXingReaderModule } from "zxing-wasm/reader";
|
||||
import { type BarcodeFormat, type ReadResultBarcodeFormat } from "./utils.js";
|
||||
export { type BarcodeFormat } from "./utils.js";
|
||||
export interface BarcodeDetectorOptions {
|
||||
formats?: BarcodeFormat[];
|
||||
}
|
||||
export interface Point2D {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
export interface DetectedBarcode {
|
||||
boundingBox: DOMRectReadOnly;
|
||||
rawValue: string;
|
||||
format: ReadResultBarcodeFormat;
|
||||
cornerPoints: [Point2D, Point2D, Point2D, Point2D];
|
||||
}
|
||||
interface CustomEventMap {
|
||||
load: CustomEvent<ZXingReaderModule>;
|
||||
error: CustomEvent<unknown>;
|
||||
}
|
||||
type ChangeEventListener = <K extends keyof CustomEventMap>(type: K, callback: ((evt: CustomEventMap[K]) => void) | {
|
||||
handleEvent(evt: CustomEventMap[K]): void;
|
||||
} | null, options?: boolean | AddEventListenerOptions | undefined) => void;
|
||||
export interface BarcodeDetector {
|
||||
addEventListener: ChangeEventListener;
|
||||
removeEventListener: ChangeEventListener;
|
||||
}
|
||||
export declare class BarcodeDetector extends EventTarget {
|
||||
#private;
|
||||
constructor(barcodeDectorOptions?: BarcodeDetectorOptions);
|
||||
static getSupportedFormats(): Promise<readonly BarcodeFormat[]>;
|
||||
detect(image: ImageBitmapSourceWebCodecs): Promise<DetectedBarcode[]>;
|
||||
}
|
||||
export { setZXingModuleOverrides } from "zxing-wasm/reader";
|
2
node_modules/barcode-detector/dist/cjs/index.d.ts
generated
vendored
Normal file
2
node_modules/barcode-detector/dist/cjs/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
import "./side-effects.js";
|
||||
export * from "./pure.js";
|
1
node_modules/barcode-detector/dist/cjs/index.js
generated
vendored
Normal file
1
node_modules/barcode-detector/dist/cjs/index.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("./side-effects.js");const e=require("./pure.js");exports.BarcodeDetector=e.BarcodeDetector;exports.setZXingModuleOverrides=e.setZXingModuleOverrides;
|
3
node_modules/barcode-detector/dist/cjs/package.json
generated
vendored
Normal file
3
node_modules/barcode-detector/dist/cjs/package.json
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
1
node_modules/barcode-detector/dist/cjs/pure.d.ts
generated
vendored
Normal file
1
node_modules/barcode-detector/dist/cjs/pure.d.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from "./BarcodeDetector.js";
|
3
node_modules/barcode-detector/dist/cjs/pure.js
generated
vendored
Normal file
3
node_modules/barcode-detector/dist/cjs/pure.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
8
node_modules/barcode-detector/dist/cjs/side-effects.d.ts
generated
vendored
Normal file
8
node_modules/barcode-detector/dist/cjs/side-effects.d.ts
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
export { setZXingModuleOverrides } from "./BarcodeDetector.js";
|
||||
declare global {
|
||||
var BarcodeDetector: typeof import("./BarcodeDetector.js").BarcodeDetector;
|
||||
type BarcodeDetector = import("./BarcodeDetector.js").BarcodeDetector;
|
||||
type BarcodeFormat = import("./BarcodeDetector.js").BarcodeFormat;
|
||||
type BarcodeDetectorOptions = import("./BarcodeDetector.js").BarcodeDetectorOptions;
|
||||
type DetectedBarcode = import("./BarcodeDetector.js").DetectedBarcode;
|
||||
}
|
1
node_modules/barcode-detector/dist/cjs/side-effects.js
generated
vendored
Normal file
1
node_modules/barcode-detector/dist/cjs/side-effects.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./pure.js");var e;(e=globalThis.BarcodeDetector)!=null||(globalThis.BarcodeDetector=r.BarcodeDetector);exports.setZXingModuleOverrides=r.setZXingModuleOverrides;
|
15
node_modules/barcode-detector/dist/cjs/utils.d.ts
generated
vendored
Normal file
15
node_modules/barcode-detector/dist/cjs/utils.d.ts
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/// <reference types="dom-webcodecs" />
|
||||
import { type ReadInputBarcodeFormat, type ReadOutputBarcodeFormat } from "zxing-wasm/reader";
|
||||
export declare const BARCODE_FORMATS: ("aztec" | "code_128" | "code_39" | "code_93" | "codabar" | "databar" | "databar_expanded" | "data_matrix" | "dx_film_edge" | "ean_13" | "ean_8" | "itf" | "maxi_code" | "micro_qr_code" | "pdf417" | "qr_code" | "rm_qr_code" | "upc_a" | "upc_e" | "linear_codes" | "matrix_codes" | "unknown")[];
|
||||
export type BarcodeFormat = (typeof BARCODE_FORMATS)[number];
|
||||
export type ReadResultBarcodeFormat = Exclude<BarcodeFormat, "linear_codes" | "matrix_codes">;
|
||||
export declare const formatMap: Map<"aztec" | "code_128" | "code_39" | "code_93" | "codabar" | "databar" | "databar_expanded" | "data_matrix" | "dx_film_edge" | "ean_13" | "ean_8" | "itf" | "maxi_code" | "micro_qr_code" | "pdf417" | "qr_code" | "rm_qr_code" | "upc_a" | "upc_e" | "linear_codes" | "matrix_codes" | "unknown", ReadInputBarcodeFormat>;
|
||||
export declare function convertFormat(target: ReadOutputBarcodeFormat): ReadResultBarcodeFormat;
|
||||
export declare function isBlob(image: ImageBitmapSourceWebCodecs): image is Blob;
|
||||
export declare function getImageDataOrBlobFromImageBitmapSource(image: ImageBitmapSourceWebCodecs): Promise<ImageData | Blob | null>;
|
||||
declare global {
|
||||
interface SVGImageElement {
|
||||
decode?(): Promise<void>;
|
||||
}
|
||||
}
|
||||
export declare function addPrefixToExceptionOrError(e: unknown, prefix: string): TypeError | DOMException;
|
35
node_modules/barcode-detector/dist/es/BarcodeDetector.d.ts
generated
vendored
Normal file
35
node_modules/barcode-detector/dist/es/BarcodeDetector.d.ts
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
/// <reference types="dom-webcodecs" />
|
||||
import { type ZXingReaderModule } from "zxing-wasm/reader";
|
||||
import { type BarcodeFormat, type ReadResultBarcodeFormat } from "./utils.js";
|
||||
export { type BarcodeFormat } from "./utils.js";
|
||||
export interface BarcodeDetectorOptions {
|
||||
formats?: BarcodeFormat[];
|
||||
}
|
||||
export interface Point2D {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
export interface DetectedBarcode {
|
||||
boundingBox: DOMRectReadOnly;
|
||||
rawValue: string;
|
||||
format: ReadResultBarcodeFormat;
|
||||
cornerPoints: [Point2D, Point2D, Point2D, Point2D];
|
||||
}
|
||||
interface CustomEventMap {
|
||||
load: CustomEvent<ZXingReaderModule>;
|
||||
error: CustomEvent<unknown>;
|
||||
}
|
||||
type ChangeEventListener = <K extends keyof CustomEventMap>(type: K, callback: ((evt: CustomEventMap[K]) => void) | {
|
||||
handleEvent(evt: CustomEventMap[K]): void;
|
||||
} | null, options?: boolean | AddEventListenerOptions | undefined) => void;
|
||||
export interface BarcodeDetector {
|
||||
addEventListener: ChangeEventListener;
|
||||
removeEventListener: ChangeEventListener;
|
||||
}
|
||||
export declare class BarcodeDetector extends EventTarget {
|
||||
#private;
|
||||
constructor(barcodeDectorOptions?: BarcodeDetectorOptions);
|
||||
static getSupportedFormats(): Promise<readonly BarcodeFormat[]>;
|
||||
detect(image: ImageBitmapSourceWebCodecs): Promise<DetectedBarcode[]>;
|
||||
}
|
||||
export { setZXingModuleOverrides } from "zxing-wasm/reader";
|
2
node_modules/barcode-detector/dist/es/index.d.ts
generated
vendored
Normal file
2
node_modules/barcode-detector/dist/es/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
import "./side-effects.js";
|
||||
export * from "./pure.js";
|
6
node_modules/barcode-detector/dist/es/index.js
generated
vendored
Normal file
6
node_modules/barcode-detector/dist/es/index.js
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
import "./side-effects.js";
|
||||
import { BarcodeDetector as t, setZXingModuleOverrides as d } from "./pure.js";
|
||||
export {
|
||||
t as BarcodeDetector,
|
||||
d as setZXingModuleOverrides
|
||||
};
|
1
node_modules/barcode-detector/dist/es/pure.d.ts
generated
vendored
Normal file
1
node_modules/barcode-detector/dist/es/pure.d.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from "./BarcodeDetector.js";
|
2252
node_modules/barcode-detector/dist/es/pure.js
generated
vendored
Normal file
2252
node_modules/barcode-detector/dist/es/pure.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
node_modules/barcode-detector/dist/es/side-effects.d.ts
generated
vendored
Normal file
8
node_modules/barcode-detector/dist/es/side-effects.d.ts
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
export { setZXingModuleOverrides } from "./BarcodeDetector.js";
|
||||
declare global {
|
||||
var BarcodeDetector: typeof import("./BarcodeDetector.js").BarcodeDetector;
|
||||
type BarcodeDetector = import("./BarcodeDetector.js").BarcodeDetector;
|
||||
type BarcodeFormat = import("./BarcodeDetector.js").BarcodeFormat;
|
||||
type BarcodeDetectorOptions = import("./BarcodeDetector.js").BarcodeDetectorOptions;
|
||||
type DetectedBarcode = import("./BarcodeDetector.js").DetectedBarcode;
|
||||
}
|
7
node_modules/barcode-detector/dist/es/side-effects.js
generated
vendored
Normal file
7
node_modules/barcode-detector/dist/es/side-effects.js
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import { BarcodeDetector as o } from "./pure.js";
|
||||
import { setZXingModuleOverrides as d } from "./pure.js";
|
||||
var e;
|
||||
(e = globalThis.BarcodeDetector) != null || (globalThis.BarcodeDetector = o);
|
||||
export {
|
||||
d as setZXingModuleOverrides
|
||||
};
|
15
node_modules/barcode-detector/dist/es/utils.d.ts
generated
vendored
Normal file
15
node_modules/barcode-detector/dist/es/utils.d.ts
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/// <reference types="dom-webcodecs" />
|
||||
import { type ReadInputBarcodeFormat, type ReadOutputBarcodeFormat } from "zxing-wasm/reader";
|
||||
export declare const BARCODE_FORMATS: ("aztec" | "code_128" | "code_39" | "code_93" | "codabar" | "databar" | "databar_expanded" | "data_matrix" | "dx_film_edge" | "ean_13" | "ean_8" | "itf" | "maxi_code" | "micro_qr_code" | "pdf417" | "qr_code" | "rm_qr_code" | "upc_a" | "upc_e" | "linear_codes" | "matrix_codes" | "unknown")[];
|
||||
export type BarcodeFormat = (typeof BARCODE_FORMATS)[number];
|
||||
export type ReadResultBarcodeFormat = Exclude<BarcodeFormat, "linear_codes" | "matrix_codes">;
|
||||
export declare const formatMap: Map<"aztec" | "code_128" | "code_39" | "code_93" | "codabar" | "databar" | "databar_expanded" | "data_matrix" | "dx_film_edge" | "ean_13" | "ean_8" | "itf" | "maxi_code" | "micro_qr_code" | "pdf417" | "qr_code" | "rm_qr_code" | "upc_a" | "upc_e" | "linear_codes" | "matrix_codes" | "unknown", ReadInputBarcodeFormat>;
|
||||
export declare function convertFormat(target: ReadOutputBarcodeFormat): ReadResultBarcodeFormat;
|
||||
export declare function isBlob(image: ImageBitmapSourceWebCodecs): image is Blob;
|
||||
export declare function getImageDataOrBlobFromImageBitmapSource(image: ImageBitmapSourceWebCodecs): Promise<ImageData | Blob | null>;
|
||||
declare global {
|
||||
interface SVGImageElement {
|
||||
decode?(): Promise<void>;
|
||||
}
|
||||
}
|
||||
export declare function addPrefixToExceptionOrError(e: unknown, prefix: string): TypeError | DOMException;
|
3
node_modules/barcode-detector/dist/iife/index.js
generated
vendored
Normal file
3
node_modules/barcode-detector/dist/iife/index.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
3
node_modules/barcode-detector/dist/iife/pure.js
generated
vendored
Normal file
3
node_modules/barcode-detector/dist/iife/pure.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
3
node_modules/barcode-detector/dist/iife/side-effects.js
generated
vendored
Normal file
3
node_modules/barcode-detector/dist/iife/side-effects.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
102
node_modules/barcode-detector/package.json
generated
vendored
Normal file
102
node_modules/barcode-detector/package.json
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
{
|
||||
"name": "barcode-detector",
|
||||
"description": "A Barcode Detection API polyfill that uses ZXing webassembly under the hood",
|
||||
"private": false,
|
||||
"version": "2.2.2",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"./dist"
|
||||
],
|
||||
"main": "./dist/cjs/index.js",
|
||||
"module": "./dist/es/index.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/es/index.js",
|
||||
"require": "./dist/cjs/index.js",
|
||||
"default": "./dist/es/index.js"
|
||||
},
|
||||
"./pure": {
|
||||
"import": "./dist/es/pure.js",
|
||||
"require": "./dist/cjs/pure.js",
|
||||
"default": "./dist/es/pure.js"
|
||||
},
|
||||
"./side-effects": {
|
||||
"import": "./dist/es/side-effects.js",
|
||||
"require": "./dist/cjs/side-effects.js",
|
||||
"default": "./dist/es/side-effects.js"
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Sec-ant/barcode-detector.git"
|
||||
},
|
||||
"homepage": "https://github.com/Sec-ant/barcode-detector",
|
||||
"bugs": {
|
||||
"url": "https://github.com/Sec-ant/barcode-detector/issues",
|
||||
"email": "zzwu@zju.edu.cn"
|
||||
},
|
||||
"keywords": [
|
||||
"es6",
|
||||
"qrcode",
|
||||
"barcode",
|
||||
"barcode-detector",
|
||||
"wasm",
|
||||
"polyfill",
|
||||
"zxing",
|
||||
"esmodule",
|
||||
"webassembly"
|
||||
],
|
||||
"author": {
|
||||
"name": "Ze-Zheng Wu"
|
||||
},
|
||||
"license": "MIT",
|
||||
"config": {
|
||||
"port": "18080"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint . --ext .ts",
|
||||
"type-check": "tsc --noEmit --emitDeclarationOnly false",
|
||||
"format": "prettier . --write",
|
||||
"prebuild": "npm run lint && npm run type-check && npm run format",
|
||||
"build:es": "vite build",
|
||||
"build:cjs": "tsx ./scripts/build-cjs.ts",
|
||||
"build:iife": "tsx ./scripts/build-iife.ts",
|
||||
"build": "conc \"npm:build:es\" \"npm:build:cjs\" \"npm:build:iife\"",
|
||||
"postbuild:es": "tsc --declarationDir ./dist/es",
|
||||
"postbuild:cjs": "tsc --declarationDir ./dist/cjs",
|
||||
"start": "vite preview --outDir ./tests --port $npm_package_config_port -l silent",
|
||||
"pretest": "tsx ./scripts/list-dir.ts",
|
||||
"pretest:ui": "tsx ./scripts/list-dir.ts",
|
||||
"precoverage": "tsx ./scripts/list-dir.ts",
|
||||
"test": "start-server-and-test $npm_package_config_port 'vitest --coverage'",
|
||||
"test:ui": "start-server-and-test $npm_package_config_port 'vitest --ui --coverage'",
|
||||
"coverage": "start-server-and-test $npm_package_config_port 'vitest run --coverage'",
|
||||
"prepublishOnly": "npm run build",
|
||||
"ncu": "npx npm-check-updates --filterVersion \"/^[~^]/\" -u",
|
||||
"postncu": "npm i",
|
||||
"bump-zxing-wasm": "npm i zxing-wasm@latest --save-exact"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^6.15.0",
|
||||
"@typescript-eslint/parser": "^6.15.0",
|
||||
"@vitest/browser": "^1.1.0",
|
||||
"@vitest/coverage-istanbul": "^1.1.0",
|
||||
"@vitest/ui": "^1.1.0",
|
||||
"concurrently": "^8.2.2",
|
||||
"eslint": "^8.56.0",
|
||||
"http-server": "^14.1.1",
|
||||
"npm-check-updates": "^16.14.12",
|
||||
"playwright": "^1.40.1",
|
||||
"prettier": "^3.1.1",
|
||||
"rimraf": "^5.0.5",
|
||||
"start-server-and-test": "^2.0.3",
|
||||
"tsx": "^4.7.0",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.0.10",
|
||||
"vitest": "^1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/dom-webcodecs": "^0.1.11",
|
||||
"zxing-wasm": "1.1.3"
|
||||
}
|
||||
}
|
61
node_modules/sdp/.eslintrc
generated
vendored
Normal file
61
node_modules/sdp/.eslintrc
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"rules": {
|
||||
"array-bracket-spacing": 2,
|
||||
"block-spacing": [2, "never"],
|
||||
"brace-style": [2, "1tbs", {"allowSingleLine": false}],
|
||||
"camelcase": [2, {"properties": "always"}],
|
||||
"curly": 2,
|
||||
"default-case": 2,
|
||||
"dot-notation": 2,
|
||||
"eqeqeq": 2,
|
||||
"indent": [
|
||||
2,
|
||||
2,
|
||||
{"SwitchCase": 1}
|
||||
],
|
||||
"key-spacing": [2, {"beforeColon": false, "afterColon": true}],
|
||||
"max-len": [2, 80, 2, {"ignoreUrls": true}],
|
||||
"new-cap": [2, {"newIsCapExceptions": [
|
||||
"webkitRTCPeerConnection",
|
||||
"mozRTCPeerConnection"
|
||||
]}],
|
||||
"no-console": 0,
|
||||
"no-else-return": 2,
|
||||
"no-eval": 2,
|
||||
"no-multi-spaces": 2,
|
||||
"no-multiple-empty-lines": [2, {"max": 2}],
|
||||
"no-shadow": 2,
|
||||
"no-trailing-spaces": 2,
|
||||
"no-unused-expressions": 2,
|
||||
"no-unused-vars": [2, {"args": "none"}],
|
||||
"object-curly-spacing": [2, "never"],
|
||||
"padded-blocks": [2, "never"],
|
||||
"quotes": [
|
||||
2,
|
||||
"single"
|
||||
],
|
||||
"semi": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"keyword-spacing": 2,
|
||||
"space-before-blocks": 2,
|
||||
"space-before-function-paren": [2, "never"],
|
||||
"space-unary-ops": 2,
|
||||
"space-infix-ops": 2,
|
||||
"spaced-comment": 2,
|
||||
"valid-typeof": 2
|
||||
},
|
||||
"env": {
|
||||
"es6": true,
|
||||
"browser": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": ["eslint:recommended"],
|
||||
"globals": {
|
||||
"module": true,
|
||||
"require": true,
|
||||
"process": true,
|
||||
"Promise": true,
|
||||
}
|
||||
}
|
16
node_modules/sdp/.github/workflows/npm-test.yml
generated
vendored
Normal file
16
node_modules/sdp/.github/workflows/npm-test.yml
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
name: npm-test
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
- run: npm install
|
||||
- run: npm test
|
||||
- run: npm run coverage
|
||||
- uses: codecov/codecov-action@v1
|
||||
with:
|
||||
file: ./coverage.lcov
|
1
node_modules/sdp/.nyc_output/a9b935d8-5f14-4c64-b895-6b0ece2e9d7c.json
generated
vendored
Normal file
1
node_modules/sdp/.nyc_output/a9b935d8-5f14-4c64-b895-6b0ece2e9d7c.json
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
node_modules/sdp/.nyc_output/processinfo/a9b935d8-5f14-4c64-b895-6b0ece2e9d7c.json
generated
vendored
Normal file
1
node_modules/sdp/.nyc_output/processinfo/a9b935d8-5f14-4c64-b895-6b0ece2e9d7c.json
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"uuid":"a9b935d8-5f14-4c64-b895-6b0ece2e9d7c","parent":null,"pid":5750,"argv":["/usr/bin/node","/media/fippo/houseparty/webrtc/sdp/node_modules/.bin/mocha","test/sdp.js"],"execArgv":[],"cwd":"/media/fippo/houseparty/webrtc/sdp","time":1673267457493,"ppid":5743,"root":"9110d26c-7a83-40c7-a41d-9670d698bc02","coverageFilename":"/media/fippo/houseparty/webrtc/sdp/.nyc_output/a9b935d8-5f14-4c64-b895-6b0ece2e9d7c.json","files":["/media/fippo/houseparty/webrtc/sdp/sdp.js"]}
|
1
node_modules/sdp/.nyc_output/processinfo/index.json
generated
vendored
Normal file
1
node_modules/sdp/.nyc_output/processinfo/index.json
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"processes":{"a9b935d8-5f14-4c64-b895-6b0ece2e9d7c":{"parent":null,"children":[]}},"files":{"/media/fippo/houseparty/webrtc/sdp/sdp.js":["a9b935d8-5f14-4c64-b895-6b0ece2e9d7c"]},"externalIds":{}}
|
19
node_modules/sdp/LICENSE
generated
vendored
Normal file
19
node_modules/sdp/LICENSE
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2017 Philipp Hancke
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
4
node_modules/sdp/README.md
generated
vendored
Normal file
4
node_modules/sdp/README.md
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# SDP parsing and utlities
|
||||
originally for generating SDP from ORTC and vice versa -- see https://github.com/fippo/adapter/tree/shim-ortc
|
||||
|
||||
But it turned out to be useful for manipulating SDP outside the context of Microsofts Edge browser.
|
1083
node_modules/sdp/coverage.lcov
generated
vendored
Normal file
1083
node_modules/sdp/coverage.lcov
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
773
node_modules/sdp/dist/sdp.js
generated
vendored
Normal file
773
node_modules/sdp/dist/sdp.js
generated
vendored
Normal file
@ -0,0 +1,773 @@
|
||||
/* eslint-env node */
|
||||
'use strict';
|
||||
|
||||
// SDP helpers.
|
||||
|
||||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
||||
|
||||
var SDPUtils = {};
|
||||
|
||||
// Generate an alphanumeric identifier for cname or mids.
|
||||
// TODO: use UUIDs instead? https://gist.github.com/jed/982883
|
||||
SDPUtils.generateIdentifier = function () {
|
||||
return Math.random().toString(36).substring(2, 12);
|
||||
};
|
||||
|
||||
// The RTCP CNAME used by all peerconnections from the same JS.
|
||||
SDPUtils.localCName = SDPUtils.generateIdentifier();
|
||||
|
||||
// Splits SDP into lines, dealing with both CRLF and LF.
|
||||
SDPUtils.splitLines = function (blob) {
|
||||
return blob.trim().split('\n').map(function (line) {
|
||||
return line.trim();
|
||||
});
|
||||
};
|
||||
// Splits SDP into sessionpart and mediasections. Ensures CRLF.
|
||||
SDPUtils.splitSections = function (blob) {
|
||||
var parts = blob.split('\nm=');
|
||||
return parts.map(function (part, index) {
|
||||
return (index > 0 ? 'm=' + part : part).trim() + '\r\n';
|
||||
});
|
||||
};
|
||||
|
||||
// Returns the session description.
|
||||
SDPUtils.getDescription = function (blob) {
|
||||
var sections = SDPUtils.splitSections(blob);
|
||||
return sections && sections[0];
|
||||
};
|
||||
|
||||
// Returns the individual media sections.
|
||||
SDPUtils.getMediaSections = function (blob) {
|
||||
var sections = SDPUtils.splitSections(blob);
|
||||
sections.shift();
|
||||
return sections;
|
||||
};
|
||||
|
||||
// Returns lines that start with a certain prefix.
|
||||
SDPUtils.matchPrefix = function (blob, prefix) {
|
||||
return SDPUtils.splitLines(blob).filter(function (line) {
|
||||
return line.indexOf(prefix) === 0;
|
||||
});
|
||||
};
|
||||
|
||||
// Parses an ICE candidate line. Sample input:
|
||||
// candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8
|
||||
// rport 55996"
|
||||
// Input can be prefixed with a=.
|
||||
SDPUtils.parseCandidate = function (line) {
|
||||
var parts = void 0;
|
||||
// Parse both variants.
|
||||
if (line.indexOf('a=candidate:') === 0) {
|
||||
parts = line.substring(12).split(' ');
|
||||
} else {
|
||||
parts = line.substring(10).split(' ');
|
||||
}
|
||||
|
||||
var candidate = {
|
||||
foundation: parts[0],
|
||||
component: { 1: 'rtp', 2: 'rtcp' }[parts[1]] || parts[1],
|
||||
protocol: parts[2].toLowerCase(),
|
||||
priority: parseInt(parts[3], 10),
|
||||
ip: parts[4],
|
||||
address: parts[4], // address is an alias for ip.
|
||||
port: parseInt(parts[5], 10),
|
||||
// skip parts[6] == 'typ'
|
||||
type: parts[7]
|
||||
};
|
||||
|
||||
for (var i = 8; i < parts.length; i += 2) {
|
||||
switch (parts[i]) {
|
||||
case 'raddr':
|
||||
candidate.relatedAddress = parts[i + 1];
|
||||
break;
|
||||
case 'rport':
|
||||
candidate.relatedPort = parseInt(parts[i + 1], 10);
|
||||
break;
|
||||
case 'tcptype':
|
||||
candidate.tcpType = parts[i + 1];
|
||||
break;
|
||||
case 'ufrag':
|
||||
candidate.ufrag = parts[i + 1]; // for backward compatibility.
|
||||
candidate.usernameFragment = parts[i + 1];
|
||||
break;
|
||||
default:
|
||||
// extension handling, in particular ufrag. Don't overwrite.
|
||||
if (candidate[parts[i]] === undefined) {
|
||||
candidate[parts[i]] = parts[i + 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
};
|
||||
|
||||
// Translates a candidate object into SDP candidate attribute.
|
||||
// This does not include the a= prefix!
|
||||
SDPUtils.writeCandidate = function (candidate) {
|
||||
var sdp = [];
|
||||
sdp.push(candidate.foundation);
|
||||
|
||||
var component = candidate.component;
|
||||
if (component === 'rtp') {
|
||||
sdp.push(1);
|
||||
} else if (component === 'rtcp') {
|
||||
sdp.push(2);
|
||||
} else {
|
||||
sdp.push(component);
|
||||
}
|
||||
sdp.push(candidate.protocol.toUpperCase());
|
||||
sdp.push(candidate.priority);
|
||||
sdp.push(candidate.address || candidate.ip);
|
||||
sdp.push(candidate.port);
|
||||
|
||||
var type = candidate.type;
|
||||
sdp.push('typ');
|
||||
sdp.push(type);
|
||||
if (type !== 'host' && candidate.relatedAddress && candidate.relatedPort) {
|
||||
sdp.push('raddr');
|
||||
sdp.push(candidate.relatedAddress);
|
||||
sdp.push('rport');
|
||||
sdp.push(candidate.relatedPort);
|
||||
}
|
||||
if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {
|
||||
sdp.push('tcptype');
|
||||
sdp.push(candidate.tcpType);
|
||||
}
|
||||
if (candidate.usernameFragment || candidate.ufrag) {
|
||||
sdp.push('ufrag');
|
||||
sdp.push(candidate.usernameFragment || candidate.ufrag);
|
||||
}
|
||||
return 'candidate:' + sdp.join(' ');
|
||||
};
|
||||
|
||||
// Parses an ice-options line, returns an array of option tags.
|
||||
// Sample input:
|
||||
// a=ice-options:foo bar
|
||||
SDPUtils.parseIceOptions = function (line) {
|
||||
return line.substring(14).split(' ');
|
||||
};
|
||||
|
||||
// Parses a rtpmap line, returns RTCRtpCoddecParameters. Sample input:
|
||||
// a=rtpmap:111 opus/48000/2
|
||||
SDPUtils.parseRtpMap = function (line) {
|
||||
var parts = line.substring(9).split(' ');
|
||||
var parsed = {
|
||||
payloadType: parseInt(parts.shift(), 10) // was: id
|
||||
};
|
||||
|
||||
parts = parts[0].split('/');
|
||||
|
||||
parsed.name = parts[0];
|
||||
parsed.clockRate = parseInt(parts[1], 10); // was: clockrate
|
||||
parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;
|
||||
// legacy alias, got renamed back to channels in ORTC.
|
||||
parsed.numChannels = parsed.channels;
|
||||
return parsed;
|
||||
};
|
||||
|
||||
// Generates a rtpmap line from RTCRtpCodecCapability or
|
||||
// RTCRtpCodecParameters.
|
||||
SDPUtils.writeRtpMap = function (codec) {
|
||||
var pt = codec.payloadType;
|
||||
if (codec.preferredPayloadType !== undefined) {
|
||||
pt = codec.preferredPayloadType;
|
||||
}
|
||||
var channels = codec.channels || codec.numChannels || 1;
|
||||
return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate + (channels !== 1 ? '/' + channels : '') + '\r\n';
|
||||
};
|
||||
|
||||
// Parses a extmap line (headerextension from RFC 5285). Sample input:
|
||||
// a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
|
||||
// a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset
|
||||
SDPUtils.parseExtmap = function (line) {
|
||||
var parts = line.substring(9).split(' ');
|
||||
return {
|
||||
id: parseInt(parts[0], 10),
|
||||
direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',
|
||||
uri: parts[1],
|
||||
attributes: parts.slice(2).join(' ')
|
||||
};
|
||||
};
|
||||
|
||||
// Generates an extmap line from RTCRtpHeaderExtensionParameters or
|
||||
// RTCRtpHeaderExtension.
|
||||
SDPUtils.writeExtmap = function (headerExtension) {
|
||||
return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) + (headerExtension.direction && headerExtension.direction !== 'sendrecv' ? '/' + headerExtension.direction : '') + ' ' + headerExtension.uri + (headerExtension.attributes ? ' ' + headerExtension.attributes : '') + '\r\n';
|
||||
};
|
||||
|
||||
// Parses a fmtp line, returns dictionary. Sample input:
|
||||
// a=fmtp:96 vbr=on;cng=on
|
||||
// Also deals with vbr=on; cng=on
|
||||
SDPUtils.parseFmtp = function (line) {
|
||||
var parsed = {};
|
||||
var kv = void 0;
|
||||
var parts = line.substring(line.indexOf(' ') + 1).split(';');
|
||||
for (var j = 0; j < parts.length; j++) {
|
||||
kv = parts[j].trim().split('=');
|
||||
parsed[kv[0].trim()] = kv[1];
|
||||
}
|
||||
return parsed;
|
||||
};
|
||||
|
||||
// Generates a fmtp line from RTCRtpCodecCapability or RTCRtpCodecParameters.
|
||||
SDPUtils.writeFmtp = function (codec) {
|
||||
var line = '';
|
||||
var pt = codec.payloadType;
|
||||
if (codec.preferredPayloadType !== undefined) {
|
||||
pt = codec.preferredPayloadType;
|
||||
}
|
||||
if (codec.parameters && Object.keys(codec.parameters).length) {
|
||||
var params = [];
|
||||
Object.keys(codec.parameters).forEach(function (param) {
|
||||
if (codec.parameters[param] !== undefined) {
|
||||
params.push(param + '=' + codec.parameters[param]);
|
||||
} else {
|
||||
params.push(param);
|
||||
}
|
||||
});
|
||||
line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\r\n';
|
||||
}
|
||||
return line;
|
||||
};
|
||||
|
||||
// Parses a rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:
|
||||
// a=rtcp-fb:98 nack rpsi
|
||||
SDPUtils.parseRtcpFb = function (line) {
|
||||
var parts = line.substring(line.indexOf(' ') + 1).split(' ');
|
||||
return {
|
||||
type: parts.shift(),
|
||||
parameter: parts.join(' ')
|
||||
};
|
||||
};
|
||||
|
||||
// Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.
|
||||
SDPUtils.writeRtcpFb = function (codec) {
|
||||
var lines = '';
|
||||
var pt = codec.payloadType;
|
||||
if (codec.preferredPayloadType !== undefined) {
|
||||
pt = codec.preferredPayloadType;
|
||||
}
|
||||
if (codec.rtcpFeedback && codec.rtcpFeedback.length) {
|
||||
// FIXME: special handling for trr-int?
|
||||
codec.rtcpFeedback.forEach(function (fb) {
|
||||
lines += 'a=rtcp-fb:' + pt + ' ' + fb.type + (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') + '\r\n';
|
||||
});
|
||||
}
|
||||
return lines;
|
||||
};
|
||||
|
||||
// Parses a RFC 5576 ssrc media attribute. Sample input:
|
||||
// a=ssrc:3735928559 cname:something
|
||||
SDPUtils.parseSsrcMedia = function (line) {
|
||||
var sp = line.indexOf(' ');
|
||||
var parts = {
|
||||
ssrc: parseInt(line.substring(7, sp), 10)
|
||||
};
|
||||
var colon = line.indexOf(':', sp);
|
||||
if (colon > -1) {
|
||||
parts.attribute = line.substring(sp + 1, colon);
|
||||
parts.value = line.substring(colon + 1);
|
||||
} else {
|
||||
parts.attribute = line.substring(sp + 1);
|
||||
}
|
||||
return parts;
|
||||
};
|
||||
|
||||
// Parse a ssrc-group line (see RFC 5576). Sample input:
|
||||
// a=ssrc-group:semantics 12 34
|
||||
SDPUtils.parseSsrcGroup = function (line) {
|
||||
var parts = line.substring(13).split(' ');
|
||||
return {
|
||||
semantics: parts.shift(),
|
||||
ssrcs: parts.map(function (ssrc) {
|
||||
return parseInt(ssrc, 10);
|
||||
})
|
||||
};
|
||||
};
|
||||
|
||||
// Extracts the MID (RFC 5888) from a media section.
|
||||
// Returns the MID or undefined if no mid line was found.
|
||||
SDPUtils.getMid = function (mediaSection) {
|
||||
var mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];
|
||||
if (mid) {
|
||||
return mid.substring(6);
|
||||
}
|
||||
};
|
||||
|
||||
// Parses a fingerprint line for DTLS-SRTP.
|
||||
SDPUtils.parseFingerprint = function (line) {
|
||||
var parts = line.substring(14).split(' ');
|
||||
return {
|
||||
algorithm: parts[0].toLowerCase(), // algorithm is case-sensitive in Edge.
|
||||
value: parts[1].toUpperCase() // the definition is upper-case in RFC 4572.
|
||||
};
|
||||
};
|
||||
|
||||
// Extracts DTLS parameters from SDP media section or sessionpart.
|
||||
// FIXME: for consistency with other functions this should only
|
||||
// get the fingerprint line as input. See also getIceParameters.
|
||||
SDPUtils.getDtlsParameters = function (mediaSection, sessionpart) {
|
||||
var lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=fingerprint:');
|
||||
// Note: a=setup line is ignored since we use the 'auto' role in Edge.
|
||||
return {
|
||||
role: 'auto',
|
||||
fingerprints: lines.map(SDPUtils.parseFingerprint)
|
||||
};
|
||||
};
|
||||
|
||||
// Serializes DTLS parameters to SDP.
|
||||
SDPUtils.writeDtlsParameters = function (params, setupType) {
|
||||
var sdp = 'a=setup:' + setupType + '\r\n';
|
||||
params.fingerprints.forEach(function (fp) {
|
||||
sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\r\n';
|
||||
});
|
||||
return sdp;
|
||||
};
|
||||
|
||||
// Parses a=crypto lines into
|
||||
// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members
|
||||
SDPUtils.parseCryptoLine = function (line) {
|
||||
var parts = line.substring(9).split(' ');
|
||||
return {
|
||||
tag: parseInt(parts[0], 10),
|
||||
cryptoSuite: parts[1],
|
||||
keyParams: parts[2],
|
||||
sessionParams: parts.slice(3)
|
||||
};
|
||||
};
|
||||
|
||||
SDPUtils.writeCryptoLine = function (parameters) {
|
||||
return 'a=crypto:' + parameters.tag + ' ' + parameters.cryptoSuite + ' ' + (_typeof(parameters.keyParams) === 'object' ? SDPUtils.writeCryptoKeyParams(parameters.keyParams) : parameters.keyParams) + (parameters.sessionParams ? ' ' + parameters.sessionParams.join(' ') : '') + '\r\n';
|
||||
};
|
||||
|
||||
// Parses the crypto key parameters into
|
||||
// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam*
|
||||
SDPUtils.parseCryptoKeyParams = function (keyParams) {
|
||||
if (keyParams.indexOf('inline:') !== 0) {
|
||||
return null;
|
||||
}
|
||||
var parts = keyParams.substring(7).split('|');
|
||||
return {
|
||||
keyMethod: 'inline',
|
||||
keySalt: parts[0],
|
||||
lifeTime: parts[1],
|
||||
mkiValue: parts[2] ? parts[2].split(':')[0] : undefined,
|
||||
mkiLength: parts[2] ? parts[2].split(':')[1] : undefined
|
||||
};
|
||||
};
|
||||
|
||||
SDPUtils.writeCryptoKeyParams = function (keyParams) {
|
||||
return keyParams.keyMethod + ':' + keyParams.keySalt + (keyParams.lifeTime ? '|' + keyParams.lifeTime : '') + (keyParams.mkiValue && keyParams.mkiLength ? '|' + keyParams.mkiValue + ':' + keyParams.mkiLength : '');
|
||||
};
|
||||
|
||||
// Extracts all SDES parameters.
|
||||
SDPUtils.getCryptoParameters = function (mediaSection, sessionpart) {
|
||||
var lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=crypto:');
|
||||
return lines.map(SDPUtils.parseCryptoLine);
|
||||
};
|
||||
|
||||
// Parses ICE information from SDP media section or sessionpart.
|
||||
// FIXME: for consistency with other functions this should only
|
||||
// get the ice-ufrag and ice-pwd lines as input.
|
||||
SDPUtils.getIceParameters = function (mediaSection, sessionpart) {
|
||||
var ufrag = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-ufrag:')[0];
|
||||
var pwd = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-pwd:')[0];
|
||||
if (!(ufrag && pwd)) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
usernameFragment: ufrag.substring(12),
|
||||
password: pwd.substring(10)
|
||||
};
|
||||
};
|
||||
|
||||
// Serializes ICE parameters to SDP.
|
||||
SDPUtils.writeIceParameters = function (params) {
|
||||
var sdp = 'a=ice-ufrag:' + params.usernameFragment + '\r\n' + 'a=ice-pwd:' + params.password + '\r\n';
|
||||
if (params.iceLite) {
|
||||
sdp += 'a=ice-lite\r\n';
|
||||
}
|
||||
return sdp;
|
||||
};
|
||||
|
||||
// Parses the SDP media section and returns RTCRtpParameters.
|
||||
SDPUtils.parseRtpParameters = function (mediaSection) {
|
||||
var description = {
|
||||
codecs: [],
|
||||
headerExtensions: [],
|
||||
fecMechanisms: [],
|
||||
rtcp: []
|
||||
};
|
||||
var lines = SDPUtils.splitLines(mediaSection);
|
||||
var mline = lines[0].split(' ');
|
||||
description.profile = mline[2];
|
||||
for (var i = 3; i < mline.length; i++) {
|
||||
// find all codecs from mline[3..]
|
||||
var pt = mline[i];
|
||||
var rtpmapline = SDPUtils.matchPrefix(mediaSection, 'a=rtpmap:' + pt + ' ')[0];
|
||||
if (rtpmapline) {
|
||||
var codec = SDPUtils.parseRtpMap(rtpmapline);
|
||||
var fmtps = SDPUtils.matchPrefix(mediaSection, 'a=fmtp:' + pt + ' ');
|
||||
// Only the first a=fmtp:<pt> is considered.
|
||||
codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};
|
||||
codec.rtcpFeedback = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:' + pt + ' ').map(SDPUtils.parseRtcpFb);
|
||||
description.codecs.push(codec);
|
||||
// parse FEC mechanisms from rtpmap lines.
|
||||
switch (codec.name.toUpperCase()) {
|
||||
case 'RED':
|
||||
case 'ULPFEC':
|
||||
description.fecMechanisms.push(codec.name.toUpperCase());
|
||||
break;
|
||||
default:
|
||||
// only RED and ULPFEC are recognized as FEC mechanisms.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(function (line) {
|
||||
description.headerExtensions.push(SDPUtils.parseExtmap(line));
|
||||
});
|
||||
var wildcardRtcpFb = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:* ').map(SDPUtils.parseRtcpFb);
|
||||
description.codecs.forEach(function (codec) {
|
||||
wildcardRtcpFb.forEach(function (fb) {
|
||||
var duplicate = codec.rtcpFeedback.find(function (existingFeedback) {
|
||||
return existingFeedback.type === fb.type && existingFeedback.parameter === fb.parameter;
|
||||
});
|
||||
if (!duplicate) {
|
||||
codec.rtcpFeedback.push(fb);
|
||||
}
|
||||
});
|
||||
});
|
||||
// FIXME: parse rtcp.
|
||||
return description;
|
||||
};
|
||||
|
||||
// Generates parts of the SDP media section describing the capabilities /
|
||||
// parameters.
|
||||
SDPUtils.writeRtpDescription = function (kind, caps) {
|
||||
var sdp = '';
|
||||
|
||||
// Build the mline.
|
||||
sdp += 'm=' + kind + ' ';
|
||||
sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.
|
||||
sdp += ' ' + (caps.profile || 'UDP/TLS/RTP/SAVPF') + ' ';
|
||||
sdp += caps.codecs.map(function (codec) {
|
||||
if (codec.preferredPayloadType !== undefined) {
|
||||
return codec.preferredPayloadType;
|
||||
}
|
||||
return codec.payloadType;
|
||||
}).join(' ') + '\r\n';
|
||||
|
||||
sdp += 'c=IN IP4 0.0.0.0\r\n';
|
||||
sdp += 'a=rtcp:9 IN IP4 0.0.0.0\r\n';
|
||||
|
||||
// Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.
|
||||
caps.codecs.forEach(function (codec) {
|
||||
sdp += SDPUtils.writeRtpMap(codec);
|
||||
sdp += SDPUtils.writeFmtp(codec);
|
||||
sdp += SDPUtils.writeRtcpFb(codec);
|
||||
});
|
||||
var maxptime = 0;
|
||||
caps.codecs.forEach(function (codec) {
|
||||
if (codec.maxptime > maxptime) {
|
||||
maxptime = codec.maxptime;
|
||||
}
|
||||
});
|
||||
if (maxptime > 0) {
|
||||
sdp += 'a=maxptime:' + maxptime + '\r\n';
|
||||
}
|
||||
|
||||
if (caps.headerExtensions) {
|
||||
caps.headerExtensions.forEach(function (extension) {
|
||||
sdp += SDPUtils.writeExtmap(extension);
|
||||
});
|
||||
}
|
||||
// FIXME: write fecMechanisms.
|
||||
return sdp;
|
||||
};
|
||||
|
||||
// Parses the SDP media section and returns an array of
|
||||
// RTCRtpEncodingParameters.
|
||||
SDPUtils.parseRtpEncodingParameters = function (mediaSection) {
|
||||
var encodingParameters = [];
|
||||
var description = SDPUtils.parseRtpParameters(mediaSection);
|
||||
var hasRed = description.fecMechanisms.indexOf('RED') !== -1;
|
||||
var hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1;
|
||||
|
||||
// filter a=ssrc:... cname:, ignore PlanB-msid
|
||||
var ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) {
|
||||
return SDPUtils.parseSsrcMedia(line);
|
||||
}).filter(function (parts) {
|
||||
return parts.attribute === 'cname';
|
||||
});
|
||||
var primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;
|
||||
var secondarySsrc = void 0;
|
||||
|
||||
var flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID').map(function (line) {
|
||||
var parts = line.substring(17).split(' ');
|
||||
return parts.map(function (part) {
|
||||
return parseInt(part, 10);
|
||||
});
|
||||
});
|
||||
if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {
|
||||
secondarySsrc = flows[0][1];
|
||||
}
|
||||
|
||||
description.codecs.forEach(function (codec) {
|
||||
if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {
|
||||
var encParam = {
|
||||
ssrc: primarySsrc,
|
||||
codecPayloadType: parseInt(codec.parameters.apt, 10)
|
||||
};
|
||||
if (primarySsrc && secondarySsrc) {
|
||||
encParam.rtx = { ssrc: secondarySsrc };
|
||||
}
|
||||
encodingParameters.push(encParam);
|
||||
if (hasRed) {
|
||||
encParam = JSON.parse(JSON.stringify(encParam));
|
||||
encParam.fec = {
|
||||
ssrc: primarySsrc,
|
||||
mechanism: hasUlpfec ? 'red+ulpfec' : 'red'
|
||||
};
|
||||
encodingParameters.push(encParam);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (encodingParameters.length === 0 && primarySsrc) {
|
||||
encodingParameters.push({
|
||||
ssrc: primarySsrc
|
||||
});
|
||||
}
|
||||
|
||||
// we support both b=AS and b=TIAS but interpret AS as TIAS.
|
||||
var bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');
|
||||
if (bandwidth.length) {
|
||||
if (bandwidth[0].indexOf('b=TIAS:') === 0) {
|
||||
bandwidth = parseInt(bandwidth[0].substring(7), 10);
|
||||
} else if (bandwidth[0].indexOf('b=AS:') === 0) {
|
||||
// use formula from JSEP to convert b=AS to TIAS value.
|
||||
bandwidth = parseInt(bandwidth[0].substring(5), 10) * 1000 * 0.95 - 50 * 40 * 8;
|
||||
} else {
|
||||
bandwidth = undefined;
|
||||
}
|
||||
encodingParameters.forEach(function (params) {
|
||||
params.maxBitrate = bandwidth;
|
||||
});
|
||||
}
|
||||
return encodingParameters;
|
||||
};
|
||||
|
||||
// parses http://draft.ortc.org/#rtcrtcpparameters*
|
||||
SDPUtils.parseRtcpParameters = function (mediaSection) {
|
||||
var rtcpParameters = {};
|
||||
|
||||
// Gets the first SSRC. Note that with RTX there might be multiple
|
||||
// SSRCs.
|
||||
var remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) {
|
||||
return SDPUtils.parseSsrcMedia(line);
|
||||
}).filter(function (obj) {
|
||||
return obj.attribute === 'cname';
|
||||
})[0];
|
||||
if (remoteSsrc) {
|
||||
rtcpParameters.cname = remoteSsrc.value;
|
||||
rtcpParameters.ssrc = remoteSsrc.ssrc;
|
||||
}
|
||||
|
||||
// Edge uses the compound attribute instead of reducedSize
|
||||
// compound is !reducedSize
|
||||
var rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');
|
||||
rtcpParameters.reducedSize = rsize.length > 0;
|
||||
rtcpParameters.compound = rsize.length === 0;
|
||||
|
||||
// parses the rtcp-mux attrіbute.
|
||||
// Note that Edge does not support unmuxed RTCP.
|
||||
var mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');
|
||||
rtcpParameters.mux = mux.length > 0;
|
||||
|
||||
return rtcpParameters;
|
||||
};
|
||||
|
||||
SDPUtils.writeRtcpParameters = function (rtcpParameters) {
|
||||
var sdp = '';
|
||||
if (rtcpParameters.reducedSize) {
|
||||
sdp += 'a=rtcp-rsize\r\n';
|
||||
}
|
||||
if (rtcpParameters.mux) {
|
||||
sdp += 'a=rtcp-mux\r\n';
|
||||
}
|
||||
if (rtcpParameters.ssrc !== undefined && rtcpParameters.cname) {
|
||||
sdp += 'a=ssrc:' + rtcpParameters.ssrc + ' cname:' + rtcpParameters.cname + '\r\n';
|
||||
}
|
||||
return sdp;
|
||||
};
|
||||
|
||||
// parses either a=msid: or a=ssrc:... msid lines and returns
|
||||
// the id of the MediaStream and MediaStreamTrack.
|
||||
SDPUtils.parseMsid = function (mediaSection) {
|
||||
var parts = void 0;
|
||||
var spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');
|
||||
if (spec.length === 1) {
|
||||
parts = spec[0].substring(7).split(' ');
|
||||
return { stream: parts[0], track: parts[1] };
|
||||
}
|
||||
var planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) {
|
||||
return SDPUtils.parseSsrcMedia(line);
|
||||
}).filter(function (msidParts) {
|
||||
return msidParts.attribute === 'msid';
|
||||
});
|
||||
if (planB.length > 0) {
|
||||
parts = planB[0].value.split(' ');
|
||||
return { stream: parts[0], track: parts[1] };
|
||||
}
|
||||
};
|
||||
|
||||
// SCTP
|
||||
// parses draft-ietf-mmusic-sctp-sdp-26 first and falls back
|
||||
// to draft-ietf-mmusic-sctp-sdp-05
|
||||
SDPUtils.parseSctpDescription = function (mediaSection) {
|
||||
var mline = SDPUtils.parseMLine(mediaSection);
|
||||
var maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:');
|
||||
var maxMessageSize = void 0;
|
||||
if (maxSizeLine.length > 0) {
|
||||
maxMessageSize = parseInt(maxSizeLine[0].substring(19), 10);
|
||||
}
|
||||
if (isNaN(maxMessageSize)) {
|
||||
maxMessageSize = 65536;
|
||||
}
|
||||
var sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:');
|
||||
if (sctpPort.length > 0) {
|
||||
return {
|
||||
port: parseInt(sctpPort[0].substring(12), 10),
|
||||
protocol: mline.fmt,
|
||||
maxMessageSize: maxMessageSize
|
||||
};
|
||||
}
|
||||
var sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:');
|
||||
if (sctpMapLines.length > 0) {
|
||||
var parts = sctpMapLines[0].substring(10).split(' ');
|
||||
return {
|
||||
port: parseInt(parts[0], 10),
|
||||
protocol: parts[1],
|
||||
maxMessageSize: maxMessageSize
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// SCTP
|
||||
// outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers
|
||||
// support by now receiving in this format, unless we originally parsed
|
||||
// as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line
|
||||
// protocol of DTLS/SCTP -- without UDP/ or TCP/)
|
||||
SDPUtils.writeSctpDescription = function (media, sctp) {
|
||||
var output = [];
|
||||
if (media.protocol !== 'DTLS/SCTP') {
|
||||
output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctp-port:' + sctp.port + '\r\n'];
|
||||
} else {
|
||||
output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\r\n'];
|
||||
}
|
||||
if (sctp.maxMessageSize !== undefined) {
|
||||
output.push('a=max-message-size:' + sctp.maxMessageSize + '\r\n');
|
||||
}
|
||||
return output.join('');
|
||||
};
|
||||
|
||||
// Generate a session ID for SDP.
|
||||
// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1
|
||||
// recommends using a cryptographically random +ve 64-bit value
|
||||
// but right now this should be acceptable and within the right range
|
||||
SDPUtils.generateSessionId = function () {
|
||||
return Math.random().toString().substr(2, 22);
|
||||
};
|
||||
|
||||
// Write boiler plate for start of SDP
|
||||
// sessId argument is optional - if not supplied it will
|
||||
// be generated randomly
|
||||
// sessVersion is optional and defaults to 2
|
||||
// sessUser is optional and defaults to 'thisisadapterortc'
|
||||
SDPUtils.writeSessionBoilerplate = function (sessId, sessVer, sessUser) {
|
||||
var sessionId = void 0;
|
||||
var version = sessVer !== undefined ? sessVer : 2;
|
||||
if (sessId) {
|
||||
sessionId = sessId;
|
||||
} else {
|
||||
sessionId = SDPUtils.generateSessionId();
|
||||
}
|
||||
var user = sessUser || 'thisisadapterortc';
|
||||
// FIXME: sess-id should be an NTP timestamp.
|
||||
return 'v=0\r\n' + 'o=' + user + ' ' + sessionId + ' ' + version + ' IN IP4 127.0.0.1\r\n' + 's=-\r\n' + 't=0 0\r\n';
|
||||
};
|
||||
|
||||
// Gets the direction from the mediaSection or the sessionpart.
|
||||
SDPUtils.getDirection = function (mediaSection, sessionpart) {
|
||||
// Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.
|
||||
var lines = SDPUtils.splitLines(mediaSection);
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
switch (lines[i]) {
|
||||
case 'a=sendrecv':
|
||||
case 'a=sendonly':
|
||||
case 'a=recvonly':
|
||||
case 'a=inactive':
|
||||
return lines[i].substring(2);
|
||||
default:
|
||||
// FIXME: What should happen here?
|
||||
}
|
||||
}
|
||||
if (sessionpart) {
|
||||
return SDPUtils.getDirection(sessionpart);
|
||||
}
|
||||
return 'sendrecv';
|
||||
};
|
||||
|
||||
SDPUtils.getKind = function (mediaSection) {
|
||||
var lines = SDPUtils.splitLines(mediaSection);
|
||||
var mline = lines[0].split(' ');
|
||||
return mline[0].substring(2);
|
||||
};
|
||||
|
||||
SDPUtils.isRejected = function (mediaSection) {
|
||||
return mediaSection.split(' ', 2)[1] === '0';
|
||||
};
|
||||
|
||||
SDPUtils.parseMLine = function (mediaSection) {
|
||||
var lines = SDPUtils.splitLines(mediaSection);
|
||||
var parts = lines[0].substring(2).split(' ');
|
||||
return {
|
||||
kind: parts[0],
|
||||
port: parseInt(parts[1], 10),
|
||||
protocol: parts[2],
|
||||
fmt: parts.slice(3).join(' ')
|
||||
};
|
||||
};
|
||||
|
||||
SDPUtils.parseOLine = function (mediaSection) {
|
||||
var line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];
|
||||
var parts = line.substring(2).split(' ');
|
||||
return {
|
||||
username: parts[0],
|
||||
sessionId: parts[1],
|
||||
sessionVersion: parseInt(parts[2], 10),
|
||||
netType: parts[3],
|
||||
addressType: parts[4],
|
||||
address: parts[5]
|
||||
};
|
||||
};
|
||||
|
||||
// a very naive interpretation of a valid SDP.
|
||||
SDPUtils.isValidSDP = function (blob) {
|
||||
if (typeof blob !== 'string' || blob.length === 0) {
|
||||
return false;
|
||||
}
|
||||
var lines = SDPUtils.splitLines(blob);
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {
|
||||
return false;
|
||||
}
|
||||
// TODO: check the modifier a bit more.
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Expose public methods.
|
||||
if ((typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') {
|
||||
module.exports = SDPUtils;
|
||||
}
|
36
node_modules/sdp/package.json
generated
vendored
Normal file
36
node_modules/sdp/package.json
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "sdp",
|
||||
"version": "3.2.0",
|
||||
"description": "SDP parsing and serialization utilities",
|
||||
"main": "dist/sdp.js",
|
||||
"module": "sdp.js",
|
||||
"typings": "sdp.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/fippo/sdp.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "babel sdp.js --presets babel-preset-env --out-dir dist",
|
||||
"coverage": "c8 report --reporter=text-lcov > coverage.lcov",
|
||||
"prepare": "npm run build",
|
||||
"test": "eslint sdp.js test/sdp.js && c8 --reporter html mocha test/sdp.js"
|
||||
},
|
||||
"keywords": [
|
||||
"sdp",
|
||||
"webrtc"
|
||||
],
|
||||
"author": "Philipp Hancke",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"c8": "^7.12.0",
|
||||
"chai": "^4.3.7",
|
||||
"codecov": "^3.6.5",
|
||||
"eslint": "^8.31.0",
|
||||
"mocha": "^10.2.0",
|
||||
"sinon": "^15.0.1",
|
||||
"sinon-chai": "^3.7.0"
|
||||
}
|
||||
}
|
220
node_modules/sdp/sdp.d.ts
generated
vendored
Normal file
220
node_modules/sdp/sdp.d.ts
generated
vendored
Normal file
@ -0,0 +1,220 @@
|
||||
export type SDPBlob = string;
|
||||
export type SDPLine = string;
|
||||
export type SDPSection = string;
|
||||
|
||||
export type SDPDirection = 'sendonly' | 'recvonly' | 'sendrecv' | 'inactive';
|
||||
|
||||
export interface SDPIceCandidate {
|
||||
foundation: string;
|
||||
component: 'rtp' | 'rtcp' | number;
|
||||
protocol: 'tcp' | 'udp';
|
||||
priority: number;
|
||||
ip: string;
|
||||
address: string;
|
||||
port: number;
|
||||
type: 'host' | 'prflx' | 'srflx' | 'relay';
|
||||
relatedAddress?: string;
|
||||
relatedPort?: number;
|
||||
tcpType?: string;
|
||||
ufrag?: string;
|
||||
usernameFragment?: string;
|
||||
}
|
||||
|
||||
export interface SDPIceParameters {
|
||||
iceLite?: boolean;
|
||||
usernameFragment: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface SDPCodecParameters {
|
||||
payloadType: number;
|
||||
preferredPayloadType?: number;
|
||||
name: string;
|
||||
clockRate: number;
|
||||
channels: number;
|
||||
numChannels?: number;
|
||||
maxptime?: number;
|
||||
}
|
||||
|
||||
export interface SDPCodecAdditionalParameters {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export interface SDPHeaderExtension {
|
||||
id: number;
|
||||
direction?: SDPDirection;
|
||||
uri: string;
|
||||
atrributes: string | undefined;
|
||||
}
|
||||
|
||||
export interface SDPFeedbackParameter {
|
||||
type: string;
|
||||
parameter: string;
|
||||
}
|
||||
|
||||
export interface SDPFingerprint {
|
||||
algorithm: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface SDPDtlsParameters {
|
||||
role: string;
|
||||
fingerprints: SDPFingerprint[];
|
||||
}
|
||||
|
||||
export interface SDPMediaSource {
|
||||
ssrc: number;
|
||||
attribute?: string;
|
||||
value?: string;
|
||||
}
|
||||
|
||||
export interface SDPMediaSourceGroup {
|
||||
semantics: string;
|
||||
ssrcs: number[];
|
||||
}
|
||||
|
||||
export interface SDPMediaStreamId {
|
||||
stream: string;
|
||||
track: string;
|
||||
}
|
||||
|
||||
export interface SDPCodec extends SDPCodecParameters {
|
||||
payloadType: number;
|
||||
preferredPayloadType?: number;
|
||||
parameters?: SDPCodecAdditionalParameters;
|
||||
rtcpFeedback?: SDPFeedbackParameter[];
|
||||
}
|
||||
|
||||
export interface SDPGroup {
|
||||
semantics: string;
|
||||
mids: string[];
|
||||
}
|
||||
|
||||
export interface SDPMLine {
|
||||
kind: string;
|
||||
port?: number;
|
||||
protocol: string;
|
||||
fmt?: string;
|
||||
}
|
||||
|
||||
export interface SDPOLine {
|
||||
username: string;
|
||||
sessionId: string;
|
||||
sessionVersion: number;
|
||||
netType: string;
|
||||
addressType: string;
|
||||
address: string;
|
||||
}
|
||||
|
||||
export interface SDPRtcpParameters {
|
||||
cname?: string;
|
||||
ssrc?: number;
|
||||
reducedSize?: boolean;
|
||||
compound?: boolean;
|
||||
mux?: boolean;
|
||||
}
|
||||
|
||||
export interface SDPEncodingParameters {
|
||||
ssrc: number;
|
||||
codecPayloadType?: number;
|
||||
rtx?: {
|
||||
ssrc: number;
|
||||
};
|
||||
fec?: {
|
||||
ssrc: number;
|
||||
mechanism: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface SDPRtpCapabilities {
|
||||
codecs: SDPCodec[];
|
||||
headerExtensions: SDPHeaderExtension[];
|
||||
fecMechanisms: string[];
|
||||
rtcp?: SDPRtcpParameters[];
|
||||
}
|
||||
|
||||
export interface SDPSctpDescription {
|
||||
port: number;
|
||||
protocol: string;
|
||||
maxMessageSize?: number;
|
||||
}
|
||||
|
||||
export const localCname: string;
|
||||
|
||||
export function generateIdentifier(): string;
|
||||
|
||||
export function splitLines(blob: SDPBlob): SDPLine[];
|
||||
export function splitSections(blob: SDPBlob): SDPSection[];
|
||||
|
||||
export function getDescription(blob: SDPBlob): SDPSection;
|
||||
export function getMediaSections(blob: SDPBlob): SDPSection[];
|
||||
|
||||
export function matchPrefix(blob: SDPBlob, prefix: string): SDPLine[];
|
||||
|
||||
export function parseCandidate(line: SDPLine): SDPIceCandidate;
|
||||
export function writeCandidate(candidate: SDPIceCandidate): SDPLine;
|
||||
|
||||
export function parseIceOptions(line: SDPLine): string[];
|
||||
|
||||
export function parseRtpMap(line: SDPLine): SDPCodecParameters;
|
||||
export function writeRtpMap(codec: SDPCodecParameters): SDPLine;
|
||||
|
||||
export function parseExtmap(line: SDPLine): SDPHeaderExtension;
|
||||
export function writeExtmap(headerExtension: SDPHeaderExtension): SDPLine;
|
||||
|
||||
export function parseFmtp(line: SDPLine): SDPCodecAdditionalParameters;
|
||||
export function writeFmtp(codec: SDPCodec): SDPLine;
|
||||
|
||||
export function parseRtcpFb(line: SDPLine): SDPFeedbackParameter;
|
||||
export function writeRtcpFb(codec: SDPCodec): SDPLine[];
|
||||
|
||||
export function parseSsrcMedia(line: SDPLine): SDPMediaSource;
|
||||
export function parseSsrcGroup(line: SDPLine): SDPMediaSourceGroup;
|
||||
|
||||
export function getMid(mediaSection: SDPSection): string;
|
||||
|
||||
export function parseFingerprint(line: SDPLine): SDPFingerprint;
|
||||
|
||||
export function getDtlsParameters(
|
||||
mediaSection: SDPSection,
|
||||
session: SDPSection
|
||||
): SDPDtlsParameters;
|
||||
export function writeDtlsParameters(params: SDPDtlsParameters, setupType: string): SDPLine;
|
||||
|
||||
export function getIceParameters(
|
||||
mediaSection: SDPSection,
|
||||
session: SDPSection
|
||||
): SDPIceParameters;
|
||||
export function writeIceParameters(params: SDPIceParameters): SDPLine;
|
||||
|
||||
export function parseRtpParameters(mediaSection: SDPSection): SDPRtpCapabilities;
|
||||
export function writeRtpDescription(kind: string, caps: SDPRtpCapabilities): SDPSection;
|
||||
|
||||
export function parseRtpEncodingParameters(mediaSection: SDPSection): SDPEncodingParameters[];
|
||||
|
||||
export function parseRtcpParameters(mediaSection: SDPSection): SDPRtcpParameters;
|
||||
export function writeRtcpParameters(params: SDPRtcpParameters): SDPLine;
|
||||
|
||||
export function parseMsid(mediaSection: SDPSection): SDPMediaStreamId;
|
||||
|
||||
export function parseSctpDescription(mediaSection: SDPSection): SDPSctpDescription;
|
||||
export function writeSctpDescription(
|
||||
mediaSection: SDPMLine,
|
||||
desc: SDPSctpDescription
|
||||
): SDPSection;
|
||||
|
||||
export function generateSessionId(): string;
|
||||
export function writeSessionBoilerplate(
|
||||
sessId?: string,
|
||||
sessVer?: number,
|
||||
sessUser?: string
|
||||
): SDPBlob;
|
||||
|
||||
export function getDirection(mediaSection: SDPSection, sessionpart: SDPSection): SDPDirection;
|
||||
export function getKind(mediaSection: SDPSection): string;
|
||||
export function isRejected(mediaSection: SDPSection): boolean;
|
||||
|
||||
export function parseMLine(mediaSection: SDPSection): SDPMLine;
|
||||
export function parseOLine(mediaSection: SDPSection): SDPOLine;
|
||||
|
||||
export function isValidSDP(blob: SDPBlob): boolean;
|
802
node_modules/sdp/sdp.js
generated
vendored
Normal file
802
node_modules/sdp/sdp.js
generated
vendored
Normal file
@ -0,0 +1,802 @@
|
||||
/* eslint-env node */
|
||||
'use strict';
|
||||
|
||||
// SDP helpers.
|
||||
const SDPUtils = {};
|
||||
|
||||
// Generate an alphanumeric identifier for cname or mids.
|
||||
// TODO: use UUIDs instead? https://gist.github.com/jed/982883
|
||||
SDPUtils.generateIdentifier = function() {
|
||||
return Math.random().toString(36).substring(2, 12);
|
||||
};
|
||||
|
||||
// The RTCP CNAME used by all peerconnections from the same JS.
|
||||
SDPUtils.localCName = SDPUtils.generateIdentifier();
|
||||
|
||||
// Splits SDP into lines, dealing with both CRLF and LF.
|
||||
SDPUtils.splitLines = function(blob) {
|
||||
return blob.trim().split('\n').map(line => line.trim());
|
||||
};
|
||||
// Splits SDP into sessionpart and mediasections. Ensures CRLF.
|
||||
SDPUtils.splitSections = function(blob) {
|
||||
const parts = blob.split('\nm=');
|
||||
return parts.map((part, index) => (index > 0 ?
|
||||
'm=' + part : part).trim() + '\r\n');
|
||||
};
|
||||
|
||||
// Returns the session description.
|
||||
SDPUtils.getDescription = function(blob) {
|
||||
const sections = SDPUtils.splitSections(blob);
|
||||
return sections && sections[0];
|
||||
};
|
||||
|
||||
// Returns the individual media sections.
|
||||
SDPUtils.getMediaSections = function(blob) {
|
||||
const sections = SDPUtils.splitSections(blob);
|
||||
sections.shift();
|
||||
return sections;
|
||||
};
|
||||
|
||||
// Returns lines that start with a certain prefix.
|
||||
SDPUtils.matchPrefix = function(blob, prefix) {
|
||||
return SDPUtils.splitLines(blob).filter(line => line.indexOf(prefix) === 0);
|
||||
};
|
||||
|
||||
// Parses an ICE candidate line. Sample input:
|
||||
// candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8
|
||||
// rport 55996"
|
||||
// Input can be prefixed with a=.
|
||||
SDPUtils.parseCandidate = function(line) {
|
||||
let parts;
|
||||
// Parse both variants.
|
||||
if (line.indexOf('a=candidate:') === 0) {
|
||||
parts = line.substring(12).split(' ');
|
||||
} else {
|
||||
parts = line.substring(10).split(' ');
|
||||
}
|
||||
|
||||
const candidate = {
|
||||
foundation: parts[0],
|
||||
component: {1: 'rtp', 2: 'rtcp'}[parts[1]] || parts[1],
|
||||
protocol: parts[2].toLowerCase(),
|
||||
priority: parseInt(parts[3], 10),
|
||||
ip: parts[4],
|
||||
address: parts[4], // address is an alias for ip.
|
||||
port: parseInt(parts[5], 10),
|
||||
// skip parts[6] == 'typ'
|
||||
type: parts[7],
|
||||
};
|
||||
|
||||
for (let i = 8; i < parts.length; i += 2) {
|
||||
switch (parts[i]) {
|
||||
case 'raddr':
|
||||
candidate.relatedAddress = parts[i + 1];
|
||||
break;
|
||||
case 'rport':
|
||||
candidate.relatedPort = parseInt(parts[i + 1], 10);
|
||||
break;
|
||||
case 'tcptype':
|
||||
candidate.tcpType = parts[i + 1];
|
||||
break;
|
||||
case 'ufrag':
|
||||
candidate.ufrag = parts[i + 1]; // for backward compatibility.
|
||||
candidate.usernameFragment = parts[i + 1];
|
||||
break;
|
||||
default: // extension handling, in particular ufrag. Don't overwrite.
|
||||
if (candidate[parts[i]] === undefined) {
|
||||
candidate[parts[i]] = parts[i + 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
};
|
||||
|
||||
// Translates a candidate object into SDP candidate attribute.
|
||||
// This does not include the a= prefix!
|
||||
SDPUtils.writeCandidate = function(candidate) {
|
||||
const sdp = [];
|
||||
sdp.push(candidate.foundation);
|
||||
|
||||
const component = candidate.component;
|
||||
if (component === 'rtp') {
|
||||
sdp.push(1);
|
||||
} else if (component === 'rtcp') {
|
||||
sdp.push(2);
|
||||
} else {
|
||||
sdp.push(component);
|
||||
}
|
||||
sdp.push(candidate.protocol.toUpperCase());
|
||||
sdp.push(candidate.priority);
|
||||
sdp.push(candidate.address || candidate.ip);
|
||||
sdp.push(candidate.port);
|
||||
|
||||
const type = candidate.type;
|
||||
sdp.push('typ');
|
||||
sdp.push(type);
|
||||
if (type !== 'host' && candidate.relatedAddress &&
|
||||
candidate.relatedPort) {
|
||||
sdp.push('raddr');
|
||||
sdp.push(candidate.relatedAddress);
|
||||
sdp.push('rport');
|
||||
sdp.push(candidate.relatedPort);
|
||||
}
|
||||
if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {
|
||||
sdp.push('tcptype');
|
||||
sdp.push(candidate.tcpType);
|
||||
}
|
||||
if (candidate.usernameFragment || candidate.ufrag) {
|
||||
sdp.push('ufrag');
|
||||
sdp.push(candidate.usernameFragment || candidate.ufrag);
|
||||
}
|
||||
return 'candidate:' + sdp.join(' ');
|
||||
};
|
||||
|
||||
// Parses an ice-options line, returns an array of option tags.
|
||||
// Sample input:
|
||||
// a=ice-options:foo bar
|
||||
SDPUtils.parseIceOptions = function(line) {
|
||||
return line.substring(14).split(' ');
|
||||
};
|
||||
|
||||
// Parses a rtpmap line, returns RTCRtpCoddecParameters. Sample input:
|
||||
// a=rtpmap:111 opus/48000/2
|
||||
SDPUtils.parseRtpMap = function(line) {
|
||||
let parts = line.substring(9).split(' ');
|
||||
const parsed = {
|
||||
payloadType: parseInt(parts.shift(), 10), // was: id
|
||||
};
|
||||
|
||||
parts = parts[0].split('/');
|
||||
|
||||
parsed.name = parts[0];
|
||||
parsed.clockRate = parseInt(parts[1], 10); // was: clockrate
|
||||
parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;
|
||||
// legacy alias, got renamed back to channels in ORTC.
|
||||
parsed.numChannels = parsed.channels;
|
||||
return parsed;
|
||||
};
|
||||
|
||||
// Generates a rtpmap line from RTCRtpCodecCapability or
|
||||
// RTCRtpCodecParameters.
|
||||
SDPUtils.writeRtpMap = function(codec) {
|
||||
let pt = codec.payloadType;
|
||||
if (codec.preferredPayloadType !== undefined) {
|
||||
pt = codec.preferredPayloadType;
|
||||
}
|
||||
const channels = codec.channels || codec.numChannels || 1;
|
||||
return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate +
|
||||
(channels !== 1 ? '/' + channels : '') + '\r\n';
|
||||
};
|
||||
|
||||
// Parses a extmap line (headerextension from RFC 5285). Sample input:
|
||||
// a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
|
||||
// a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset
|
||||
SDPUtils.parseExtmap = function(line) {
|
||||
const parts = line.substring(9).split(' ');
|
||||
return {
|
||||
id: parseInt(parts[0], 10),
|
||||
direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',
|
||||
uri: parts[1],
|
||||
attributes: parts.slice(2).join(' '),
|
||||
};
|
||||
};
|
||||
|
||||
// Generates an extmap line from RTCRtpHeaderExtensionParameters or
|
||||
// RTCRtpHeaderExtension.
|
||||
SDPUtils.writeExtmap = function(headerExtension) {
|
||||
return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) +
|
||||
(headerExtension.direction && headerExtension.direction !== 'sendrecv'
|
||||
? '/' + headerExtension.direction
|
||||
: '') +
|
||||
' ' + headerExtension.uri +
|
||||
(headerExtension.attributes ? ' ' + headerExtension.attributes : '') +
|
||||
'\r\n';
|
||||
};
|
||||
|
||||
// Parses a fmtp line, returns dictionary. Sample input:
|
||||
// a=fmtp:96 vbr=on;cng=on
|
||||
// Also deals with vbr=on; cng=on
|
||||
SDPUtils.parseFmtp = function(line) {
|
||||
const parsed = {};
|
||||
let kv;
|
||||
const parts = line.substring(line.indexOf(' ') + 1).split(';');
|
||||
for (let j = 0; j < parts.length; j++) {
|
||||
kv = parts[j].trim().split('=');
|
||||
parsed[kv[0].trim()] = kv[1];
|
||||
}
|
||||
return parsed;
|
||||
};
|
||||
|
||||
// Generates a fmtp line from RTCRtpCodecCapability or RTCRtpCodecParameters.
|
||||
SDPUtils.writeFmtp = function(codec) {
|
||||
let line = '';
|
||||
let pt = codec.payloadType;
|
||||
if (codec.preferredPayloadType !== undefined) {
|
||||
pt = codec.preferredPayloadType;
|
||||
}
|
||||
if (codec.parameters && Object.keys(codec.parameters).length) {
|
||||
const params = [];
|
||||
Object.keys(codec.parameters).forEach(param => {
|
||||
if (codec.parameters[param] !== undefined) {
|
||||
params.push(param + '=' + codec.parameters[param]);
|
||||
} else {
|
||||
params.push(param);
|
||||
}
|
||||
});
|
||||
line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\r\n';
|
||||
}
|
||||
return line;
|
||||
};
|
||||
|
||||
// Parses a rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:
|
||||
// a=rtcp-fb:98 nack rpsi
|
||||
SDPUtils.parseRtcpFb = function(line) {
|
||||
const parts = line.substring(line.indexOf(' ') + 1).split(' ');
|
||||
return {
|
||||
type: parts.shift(),
|
||||
parameter: parts.join(' '),
|
||||
};
|
||||
};
|
||||
|
||||
// Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.
|
||||
SDPUtils.writeRtcpFb = function(codec) {
|
||||
let lines = '';
|
||||
let pt = codec.payloadType;
|
||||
if (codec.preferredPayloadType !== undefined) {
|
||||
pt = codec.preferredPayloadType;
|
||||
}
|
||||
if (codec.rtcpFeedback && codec.rtcpFeedback.length) {
|
||||
// FIXME: special handling for trr-int?
|
||||
codec.rtcpFeedback.forEach(fb => {
|
||||
lines += 'a=rtcp-fb:' + pt + ' ' + fb.type +
|
||||
(fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') +
|
||||
'\r\n';
|
||||
});
|
||||
}
|
||||
return lines;
|
||||
};
|
||||
|
||||
// Parses a RFC 5576 ssrc media attribute. Sample input:
|
||||
// a=ssrc:3735928559 cname:something
|
||||
SDPUtils.parseSsrcMedia = function(line) {
|
||||
const sp = line.indexOf(' ');
|
||||
const parts = {
|
||||
ssrc: parseInt(line.substring(7, sp), 10),
|
||||
};
|
||||
const colon = line.indexOf(':', sp);
|
||||
if (colon > -1) {
|
||||
parts.attribute = line.substring(sp + 1, colon);
|
||||
parts.value = line.substring(colon + 1);
|
||||
} else {
|
||||
parts.attribute = line.substring(sp + 1);
|
||||
}
|
||||
return parts;
|
||||
};
|
||||
|
||||
// Parse a ssrc-group line (see RFC 5576). Sample input:
|
||||
// a=ssrc-group:semantics 12 34
|
||||
SDPUtils.parseSsrcGroup = function(line) {
|
||||
const parts = line.substring(13).split(' ');
|
||||
return {
|
||||
semantics: parts.shift(),
|
||||
ssrcs: parts.map(ssrc => parseInt(ssrc, 10)),
|
||||
};
|
||||
};
|
||||
|
||||
// Extracts the MID (RFC 5888) from a media section.
|
||||
// Returns the MID or undefined if no mid line was found.
|
||||
SDPUtils.getMid = function(mediaSection) {
|
||||
const mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];
|
||||
if (mid) {
|
||||
return mid.substring(6);
|
||||
}
|
||||
};
|
||||
|
||||
// Parses a fingerprint line for DTLS-SRTP.
|
||||
SDPUtils.parseFingerprint = function(line) {
|
||||
const parts = line.substring(14).split(' ');
|
||||
return {
|
||||
algorithm: parts[0].toLowerCase(), // algorithm is case-sensitive in Edge.
|
||||
value: parts[1].toUpperCase(), // the definition is upper-case in RFC 4572.
|
||||
};
|
||||
};
|
||||
|
||||
// Extracts DTLS parameters from SDP media section or sessionpart.
|
||||
// FIXME: for consistency with other functions this should only
|
||||
// get the fingerprint line as input. See also getIceParameters.
|
||||
SDPUtils.getDtlsParameters = function(mediaSection, sessionpart) {
|
||||
const lines = SDPUtils.matchPrefix(mediaSection + sessionpart,
|
||||
'a=fingerprint:');
|
||||
// Note: a=setup line is ignored since we use the 'auto' role in Edge.
|
||||
return {
|
||||
role: 'auto',
|
||||
fingerprints: lines.map(SDPUtils.parseFingerprint),
|
||||
};
|
||||
};
|
||||
|
||||
// Serializes DTLS parameters to SDP.
|
||||
SDPUtils.writeDtlsParameters = function(params, setupType) {
|
||||
let sdp = 'a=setup:' + setupType + '\r\n';
|
||||
params.fingerprints.forEach(fp => {
|
||||
sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\r\n';
|
||||
});
|
||||
return sdp;
|
||||
};
|
||||
|
||||
// Parses a=crypto lines into
|
||||
// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members
|
||||
SDPUtils.parseCryptoLine = function(line) {
|
||||
const parts = line.substring(9).split(' ');
|
||||
return {
|
||||
tag: parseInt(parts[0], 10),
|
||||
cryptoSuite: parts[1],
|
||||
keyParams: parts[2],
|
||||
sessionParams: parts.slice(3),
|
||||
};
|
||||
};
|
||||
|
||||
SDPUtils.writeCryptoLine = function(parameters) {
|
||||
return 'a=crypto:' + parameters.tag + ' ' +
|
||||
parameters.cryptoSuite + ' ' +
|
||||
(typeof parameters.keyParams === 'object'
|
||||
? SDPUtils.writeCryptoKeyParams(parameters.keyParams)
|
||||
: parameters.keyParams) +
|
||||
(parameters.sessionParams ? ' ' + parameters.sessionParams.join(' ') : '') +
|
||||
'\r\n';
|
||||
};
|
||||
|
||||
// Parses the crypto key parameters into
|
||||
// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam*
|
||||
SDPUtils.parseCryptoKeyParams = function(keyParams) {
|
||||
if (keyParams.indexOf('inline:') !== 0) {
|
||||
return null;
|
||||
}
|
||||
const parts = keyParams.substring(7).split('|');
|
||||
return {
|
||||
keyMethod: 'inline',
|
||||
keySalt: parts[0],
|
||||
lifeTime: parts[1],
|
||||
mkiValue: parts[2] ? parts[2].split(':')[0] : undefined,
|
||||
mkiLength: parts[2] ? parts[2].split(':')[1] : undefined,
|
||||
};
|
||||
};
|
||||
|
||||
SDPUtils.writeCryptoKeyParams = function(keyParams) {
|
||||
return keyParams.keyMethod + ':'
|
||||
+ keyParams.keySalt +
|
||||
(keyParams.lifeTime ? '|' + keyParams.lifeTime : '') +
|
||||
(keyParams.mkiValue && keyParams.mkiLength
|
||||
? '|' + keyParams.mkiValue + ':' + keyParams.mkiLength
|
||||
: '');
|
||||
};
|
||||
|
||||
// Extracts all SDES parameters.
|
||||
SDPUtils.getCryptoParameters = function(mediaSection, sessionpart) {
|
||||
const lines = SDPUtils.matchPrefix(mediaSection + sessionpart,
|
||||
'a=crypto:');
|
||||
return lines.map(SDPUtils.parseCryptoLine);
|
||||
};
|
||||
|
||||
// Parses ICE information from SDP media section or sessionpart.
|
||||
// FIXME: for consistency with other functions this should only
|
||||
// get the ice-ufrag and ice-pwd lines as input.
|
||||
SDPUtils.getIceParameters = function(mediaSection, sessionpart) {
|
||||
const ufrag = SDPUtils.matchPrefix(mediaSection + sessionpart,
|
||||
'a=ice-ufrag:')[0];
|
||||
const pwd = SDPUtils.matchPrefix(mediaSection + sessionpart,
|
||||
'a=ice-pwd:')[0];
|
||||
if (!(ufrag && pwd)) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
usernameFragment: ufrag.substring(12),
|
||||
password: pwd.substring(10),
|
||||
};
|
||||
};
|
||||
|
||||
// Serializes ICE parameters to SDP.
|
||||
SDPUtils.writeIceParameters = function(params) {
|
||||
let sdp = 'a=ice-ufrag:' + params.usernameFragment + '\r\n' +
|
||||
'a=ice-pwd:' + params.password + '\r\n';
|
||||
if (params.iceLite) {
|
||||
sdp += 'a=ice-lite\r\n';
|
||||
}
|
||||
return sdp;
|
||||
};
|
||||
|
||||
// Parses the SDP media section and returns RTCRtpParameters.
|
||||
SDPUtils.parseRtpParameters = function(mediaSection) {
|
||||
const description = {
|
||||
codecs: [],
|
||||
headerExtensions: [],
|
||||
fecMechanisms: [],
|
||||
rtcp: [],
|
||||
};
|
||||
const lines = SDPUtils.splitLines(mediaSection);
|
||||
const mline = lines[0].split(' ');
|
||||
description.profile = mline[2];
|
||||
for (let i = 3; i < mline.length; i++) { // find all codecs from mline[3..]
|
||||
const pt = mline[i];
|
||||
const rtpmapline = SDPUtils.matchPrefix(
|
||||
mediaSection, 'a=rtpmap:' + pt + ' ')[0];
|
||||
if (rtpmapline) {
|
||||
const codec = SDPUtils.parseRtpMap(rtpmapline);
|
||||
const fmtps = SDPUtils.matchPrefix(
|
||||
mediaSection, 'a=fmtp:' + pt + ' ');
|
||||
// Only the first a=fmtp:<pt> is considered.
|
||||
codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};
|
||||
codec.rtcpFeedback = SDPUtils.matchPrefix(
|
||||
mediaSection, 'a=rtcp-fb:' + pt + ' ')
|
||||
.map(SDPUtils.parseRtcpFb);
|
||||
description.codecs.push(codec);
|
||||
// parse FEC mechanisms from rtpmap lines.
|
||||
switch (codec.name.toUpperCase()) {
|
||||
case 'RED':
|
||||
case 'ULPFEC':
|
||||
description.fecMechanisms.push(codec.name.toUpperCase());
|
||||
break;
|
||||
default: // only RED and ULPFEC are recognized as FEC mechanisms.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(line => {
|
||||
description.headerExtensions.push(SDPUtils.parseExtmap(line));
|
||||
});
|
||||
const wildcardRtcpFb = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:* ')
|
||||
.map(SDPUtils.parseRtcpFb);
|
||||
description.codecs.forEach(codec => {
|
||||
wildcardRtcpFb.forEach(fb=> {
|
||||
const duplicate = codec.rtcpFeedback.find(existingFeedback => {
|
||||
return existingFeedback.type === fb.type &&
|
||||
existingFeedback.parameter === fb.parameter;
|
||||
});
|
||||
if (!duplicate) {
|
||||
codec.rtcpFeedback.push(fb);
|
||||
}
|
||||
});
|
||||
});
|
||||
// FIXME: parse rtcp.
|
||||
return description;
|
||||
};
|
||||
|
||||
// Generates parts of the SDP media section describing the capabilities /
|
||||
// parameters.
|
||||
SDPUtils.writeRtpDescription = function(kind, caps) {
|
||||
let sdp = '';
|
||||
|
||||
// Build the mline.
|
||||
sdp += 'm=' + kind + ' ';
|
||||
sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.
|
||||
sdp += ' ' + (caps.profile || 'UDP/TLS/RTP/SAVPF') + ' ';
|
||||
sdp += caps.codecs.map(codec => {
|
||||
if (codec.preferredPayloadType !== undefined) {
|
||||
return codec.preferredPayloadType;
|
||||
}
|
||||
return codec.payloadType;
|
||||
}).join(' ') + '\r\n';
|
||||
|
||||
sdp += 'c=IN IP4 0.0.0.0\r\n';
|
||||
sdp += 'a=rtcp:9 IN IP4 0.0.0.0\r\n';
|
||||
|
||||
// Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.
|
||||
caps.codecs.forEach(codec => {
|
||||
sdp += SDPUtils.writeRtpMap(codec);
|
||||
sdp += SDPUtils.writeFmtp(codec);
|
||||
sdp += SDPUtils.writeRtcpFb(codec);
|
||||
});
|
||||
let maxptime = 0;
|
||||
caps.codecs.forEach(codec => {
|
||||
if (codec.maxptime > maxptime) {
|
||||
maxptime = codec.maxptime;
|
||||
}
|
||||
});
|
||||
if (maxptime > 0) {
|
||||
sdp += 'a=maxptime:' + maxptime + '\r\n';
|
||||
}
|
||||
|
||||
if (caps.headerExtensions) {
|
||||
caps.headerExtensions.forEach(extension => {
|
||||
sdp += SDPUtils.writeExtmap(extension);
|
||||
});
|
||||
}
|
||||
// FIXME: write fecMechanisms.
|
||||
return sdp;
|
||||
};
|
||||
|
||||
// Parses the SDP media section and returns an array of
|
||||
// RTCRtpEncodingParameters.
|
||||
SDPUtils.parseRtpEncodingParameters = function(mediaSection) {
|
||||
const encodingParameters = [];
|
||||
const description = SDPUtils.parseRtpParameters(mediaSection);
|
||||
const hasRed = description.fecMechanisms.indexOf('RED') !== -1;
|
||||
const hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1;
|
||||
|
||||
// filter a=ssrc:... cname:, ignore PlanB-msid
|
||||
const ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')
|
||||
.map(line => SDPUtils.parseSsrcMedia(line))
|
||||
.filter(parts => parts.attribute === 'cname');
|
||||
const primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;
|
||||
let secondarySsrc;
|
||||
|
||||
const flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID')
|
||||
.map(line => {
|
||||
const parts = line.substring(17).split(' ');
|
||||
return parts.map(part => parseInt(part, 10));
|
||||
});
|
||||
if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {
|
||||
secondarySsrc = flows[0][1];
|
||||
}
|
||||
|
||||
description.codecs.forEach(codec => {
|
||||
if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {
|
||||
let encParam = {
|
||||
ssrc: primarySsrc,
|
||||
codecPayloadType: parseInt(codec.parameters.apt, 10),
|
||||
};
|
||||
if (primarySsrc && secondarySsrc) {
|
||||
encParam.rtx = {ssrc: secondarySsrc};
|
||||
}
|
||||
encodingParameters.push(encParam);
|
||||
if (hasRed) {
|
||||
encParam = JSON.parse(JSON.stringify(encParam));
|
||||
encParam.fec = {
|
||||
ssrc: primarySsrc,
|
||||
mechanism: hasUlpfec ? 'red+ulpfec' : 'red',
|
||||
};
|
||||
encodingParameters.push(encParam);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (encodingParameters.length === 0 && primarySsrc) {
|
||||
encodingParameters.push({
|
||||
ssrc: primarySsrc,
|
||||
});
|
||||
}
|
||||
|
||||
// we support both b=AS and b=TIAS but interpret AS as TIAS.
|
||||
let bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');
|
||||
if (bandwidth.length) {
|
||||
if (bandwidth[0].indexOf('b=TIAS:') === 0) {
|
||||
bandwidth = parseInt(bandwidth[0].substring(7), 10);
|
||||
} else if (bandwidth[0].indexOf('b=AS:') === 0) {
|
||||
// use formula from JSEP to convert b=AS to TIAS value.
|
||||
bandwidth = parseInt(bandwidth[0].substring(5), 10) * 1000 * 0.95
|
||||
- (50 * 40 * 8);
|
||||
} else {
|
||||
bandwidth = undefined;
|
||||
}
|
||||
encodingParameters.forEach(params => {
|
||||
params.maxBitrate = bandwidth;
|
||||
});
|
||||
}
|
||||
return encodingParameters;
|
||||
};
|
||||
|
||||
// parses http://draft.ortc.org/#rtcrtcpparameters*
|
||||
SDPUtils.parseRtcpParameters = function(mediaSection) {
|
||||
const rtcpParameters = {};
|
||||
|
||||
// Gets the first SSRC. Note that with RTX there might be multiple
|
||||
// SSRCs.
|
||||
const remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')
|
||||
.map(line => SDPUtils.parseSsrcMedia(line))
|
||||
.filter(obj => obj.attribute === 'cname')[0];
|
||||
if (remoteSsrc) {
|
||||
rtcpParameters.cname = remoteSsrc.value;
|
||||
rtcpParameters.ssrc = remoteSsrc.ssrc;
|
||||
}
|
||||
|
||||
// Edge uses the compound attribute instead of reducedSize
|
||||
// compound is !reducedSize
|
||||
const rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');
|
||||
rtcpParameters.reducedSize = rsize.length > 0;
|
||||
rtcpParameters.compound = rsize.length === 0;
|
||||
|
||||
// parses the rtcp-mux attrіbute.
|
||||
// Note that Edge does not support unmuxed RTCP.
|
||||
const mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');
|
||||
rtcpParameters.mux = mux.length > 0;
|
||||
|
||||
return rtcpParameters;
|
||||
};
|
||||
|
||||
SDPUtils.writeRtcpParameters = function(rtcpParameters) {
|
||||
let sdp = '';
|
||||
if (rtcpParameters.reducedSize) {
|
||||
sdp += 'a=rtcp-rsize\r\n';
|
||||
}
|
||||
if (rtcpParameters.mux) {
|
||||
sdp += 'a=rtcp-mux\r\n';
|
||||
}
|
||||
if (rtcpParameters.ssrc !== undefined && rtcpParameters.cname) {
|
||||
sdp += 'a=ssrc:' + rtcpParameters.ssrc +
|
||||
' cname:' + rtcpParameters.cname + '\r\n';
|
||||
}
|
||||
return sdp;
|
||||
};
|
||||
|
||||
|
||||
// parses either a=msid: or a=ssrc:... msid lines and returns
|
||||
// the id of the MediaStream and MediaStreamTrack.
|
||||
SDPUtils.parseMsid = function(mediaSection) {
|
||||
let parts;
|
||||
const spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');
|
||||
if (spec.length === 1) {
|
||||
parts = spec[0].substring(7).split(' ');
|
||||
return {stream: parts[0], track: parts[1]};
|
||||
}
|
||||
const planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')
|
||||
.map(line => SDPUtils.parseSsrcMedia(line))
|
||||
.filter(msidParts => msidParts.attribute === 'msid');
|
||||
if (planB.length > 0) {
|
||||
parts = planB[0].value.split(' ');
|
||||
return {stream: parts[0], track: parts[1]};
|
||||
}
|
||||
};
|
||||
|
||||
// SCTP
|
||||
// parses draft-ietf-mmusic-sctp-sdp-26 first and falls back
|
||||
// to draft-ietf-mmusic-sctp-sdp-05
|
||||
SDPUtils.parseSctpDescription = function(mediaSection) {
|
||||
const mline = SDPUtils.parseMLine(mediaSection);
|
||||
const maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:');
|
||||
let maxMessageSize;
|
||||
if (maxSizeLine.length > 0) {
|
||||
maxMessageSize = parseInt(maxSizeLine[0].substring(19), 10);
|
||||
}
|
||||
if (isNaN(maxMessageSize)) {
|
||||
maxMessageSize = 65536;
|
||||
}
|
||||
const sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:');
|
||||
if (sctpPort.length > 0) {
|
||||
return {
|
||||
port: parseInt(sctpPort[0].substring(12), 10),
|
||||
protocol: mline.fmt,
|
||||
maxMessageSize,
|
||||
};
|
||||
}
|
||||
const sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:');
|
||||
if (sctpMapLines.length > 0) {
|
||||
const parts = sctpMapLines[0]
|
||||
.substring(10)
|
||||
.split(' ');
|
||||
return {
|
||||
port: parseInt(parts[0], 10),
|
||||
protocol: parts[1],
|
||||
maxMessageSize,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// SCTP
|
||||
// outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers
|
||||
// support by now receiving in this format, unless we originally parsed
|
||||
// as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line
|
||||
// protocol of DTLS/SCTP -- without UDP/ or TCP/)
|
||||
SDPUtils.writeSctpDescription = function(media, sctp) {
|
||||
let output = [];
|
||||
if (media.protocol !== 'DTLS/SCTP') {
|
||||
output = [
|
||||
'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\r\n',
|
||||
'c=IN IP4 0.0.0.0\r\n',
|
||||
'a=sctp-port:' + sctp.port + '\r\n',
|
||||
];
|
||||
} else {
|
||||
output = [
|
||||
'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\r\n',
|
||||
'c=IN IP4 0.0.0.0\r\n',
|
||||
'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\r\n',
|
||||
];
|
||||
}
|
||||
if (sctp.maxMessageSize !== undefined) {
|
||||
output.push('a=max-message-size:' + sctp.maxMessageSize + '\r\n');
|
||||
}
|
||||
return output.join('');
|
||||
};
|
||||
|
||||
// Generate a session ID for SDP.
|
||||
// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1
|
||||
// recommends using a cryptographically random +ve 64-bit value
|
||||
// but right now this should be acceptable and within the right range
|
||||
SDPUtils.generateSessionId = function() {
|
||||
return Math.random().toString().substr(2, 22);
|
||||
};
|
||||
|
||||
// Write boiler plate for start of SDP
|
||||
// sessId argument is optional - if not supplied it will
|
||||
// be generated randomly
|
||||
// sessVersion is optional and defaults to 2
|
||||
// sessUser is optional and defaults to 'thisisadapterortc'
|
||||
SDPUtils.writeSessionBoilerplate = function(sessId, sessVer, sessUser) {
|
||||
let sessionId;
|
||||
const version = sessVer !== undefined ? sessVer : 2;
|
||||
if (sessId) {
|
||||
sessionId = sessId;
|
||||
} else {
|
||||
sessionId = SDPUtils.generateSessionId();
|
||||
}
|
||||
const user = sessUser || 'thisisadapterortc';
|
||||
// FIXME: sess-id should be an NTP timestamp.
|
||||
return 'v=0\r\n' +
|
||||
'o=' + user + ' ' + sessionId + ' ' + version +
|
||||
' IN IP4 127.0.0.1\r\n' +
|
||||
's=-\r\n' +
|
||||
't=0 0\r\n';
|
||||
};
|
||||
|
||||
// Gets the direction from the mediaSection or the sessionpart.
|
||||
SDPUtils.getDirection = function(mediaSection, sessionpart) {
|
||||
// Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.
|
||||
const lines = SDPUtils.splitLines(mediaSection);
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
switch (lines[i]) {
|
||||
case 'a=sendrecv':
|
||||
case 'a=sendonly':
|
||||
case 'a=recvonly':
|
||||
case 'a=inactive':
|
||||
return lines[i].substring(2);
|
||||
default:
|
||||
// FIXME: What should happen here?
|
||||
}
|
||||
}
|
||||
if (sessionpart) {
|
||||
return SDPUtils.getDirection(sessionpart);
|
||||
}
|
||||
return 'sendrecv';
|
||||
};
|
||||
|
||||
SDPUtils.getKind = function(mediaSection) {
|
||||
const lines = SDPUtils.splitLines(mediaSection);
|
||||
const mline = lines[0].split(' ');
|
||||
return mline[0].substring(2);
|
||||
};
|
||||
|
||||
SDPUtils.isRejected = function(mediaSection) {
|
||||
return mediaSection.split(' ', 2)[1] === '0';
|
||||
};
|
||||
|
||||
SDPUtils.parseMLine = function(mediaSection) {
|
||||
const lines = SDPUtils.splitLines(mediaSection);
|
||||
const parts = lines[0].substring(2).split(' ');
|
||||
return {
|
||||
kind: parts[0],
|
||||
port: parseInt(parts[1], 10),
|
||||
protocol: parts[2],
|
||||
fmt: parts.slice(3).join(' '),
|
||||
};
|
||||
};
|
||||
|
||||
SDPUtils.parseOLine = function(mediaSection) {
|
||||
const line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];
|
||||
const parts = line.substring(2).split(' ');
|
||||
return {
|
||||
username: parts[0],
|
||||
sessionId: parts[1],
|
||||
sessionVersion: parseInt(parts[2], 10),
|
||||
netType: parts[3],
|
||||
addressType: parts[4],
|
||||
address: parts[5],
|
||||
};
|
||||
};
|
||||
|
||||
// a very naive interpretation of a valid SDP.
|
||||
SDPUtils.isValidSDP = function(blob) {
|
||||
if (typeof blob !== 'string' || blob.length === 0) {
|
||||
return false;
|
||||
}
|
||||
const lines = SDPUtils.splitLines(blob);
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {
|
||||
return false;
|
||||
}
|
||||
// TODO: check the modifier a bit more.
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Expose public methods.
|
||||
if (typeof module === 'object') {
|
||||
module.exports = SDPUtils;
|
||||
}
|
21
node_modules/vue-qrcode-reader/LICENSE
generated
vendored
Normal file
21
node_modules/vue-qrcode-reader/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Niklas Gruhn
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
205
node_modules/vue-qrcode-reader/README.md
generated
vendored
Normal file
205
node_modules/vue-qrcode-reader/README.md
generated
vendored
Normal file
@ -0,0 +1,205 @@
|
||||
<p align="center">
|
||||
<img src="https://gruhn.github.io/vue-qrcode-reader/logo.png" alt="Logo" width="240" height="240" style="max-width: 100%;">
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<a href="https://vuejs.org/">
|
||||
<img src="https://img.shields.io/badge/vue-3-brightgreen.svg" alt="for Vue 3">
|
||||
</a>
|
||||
|
||||
<a href="https://www.npmjs.com/package/vue-qrcode-reader">
|
||||
<img src="https://img.shields.io/npm/dm/vue-qrcode-reader.svg" alt="npm monthly downloads">
|
||||
</a>
|
||||
|
||||
<br>
|
||||
|
||||
<img src="https://img.shields.io/badge/Maintained%3F-yes-green.svg" alt="is maintained? yes">
|
||||
|
||||
<a href="http://opensource.org/licenses/MIT">
|
||||
<img src="https://img.shields.io/github/license/Naereen/StrapDown.js.svg" alt="licence: MIT">
|
||||
</a>
|
||||
|
||||
<a href="https://github.com/Naereen/badges">
|
||||
<img src="https://img.shields.io/badge/badges-awesome-green.svg" alt="badges = awesome">
|
||||
</a>
|
||||
|
||||
<br>
|
||||
|
||||
<a href="https://github.com/semantic-release/semantic-release">
|
||||
<img src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg" alt="uses semantic release">
|
||||
</a>
|
||||
|
||||
<a href="https://github.com/prettier/prettier">
|
||||
<img src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square" alt="code style: prettier">
|
||||
</a>
|
||||
|
||||
<br>
|
||||
|
||||
<a href="https://bundlephobia.com/result?p=vue-qrcode-reader">
|
||||
<img src="https://badgen.net/bundlephobia/minzip/vue-qrcode-reader" alt="size minified + gzipped">
|
||||
</a>
|
||||
|
||||
<a href="https://www.npmjs.com/package/vue-qrcode-reader">
|
||||
<img src="https://img.shields.io/npm/v/vue-qrcode-reader.svg" alt="npm current version">
|
||||
</a>
|
||||
|
||||
<br>
|
||||
|
||||
<a href="https://github.com/vuejs/awesome-vue">
|
||||
<img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Vue">
|
||||
</a>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://gruhn.github.io/vue-qrcode-reader/demos/FullDemo.html">live demos</a> |
|
||||
<a href="https://gruhn.github.io/vue-qrcode-reader/api/QrcodeStream.html">api reference</a>
|
||||
</p>
|
||||
|
||||
A set of Vue.js components for detecting QR codes and [various other barcode formats](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) right in the browser:
|
||||
|
||||
- :movie_camera: `QrcodeStream` continuously scans frames from a camera stream.
|
||||
- :put_litter_in_its_place: `QrcodeDropZone` is an empty region where you can drag-and-drop images to be decoded.
|
||||
- :open_file_folder: `QrcodeCapture` is a classic file upload field, instantly scanning all files you select.
|
||||
|
||||
All components are responsive.
|
||||
Beyond that, close to zero styling.
|
||||
Make them fit your layout.
|
||||
Usage is simple and straight forward:
|
||||
|
||||
```html
|
||||
<qrcode-stream @detect="onDetect"></qrcode-stream>
|
||||
```
|
||||
|
||||
```js
|
||||
methods: {
|
||||
onDetect (detectedCodes) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Preview
|
||||
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/gruhn/vue-qrcode-reader/master/.github/preview1.gif" width="280" alt="preview screencast 1" />
|
||||
<img src="https://raw.githubusercontent.com/gruhn/vue-qrcode-reader/master/.github/preview2.gif" width="280" alt="preview screencast 2" />
|
||||
</p>
|
||||
|
||||
### Related Projects
|
||||
|
||||
* [Barcode Detector Polyfill](https://github.com/Sec-ant/barcode-detector)
|
||||
* [Svelte Port](https://github.com/ollema/svelte-qrcode-reader)
|
||||
|
||||
# Installation :package:
|
||||
|
||||
## With NPM
|
||||
|
||||
Run
|
||||
|
||||
```bash
|
||||
npm install vue-qrcode-reader
|
||||
```
|
||||
|
||||
You can import the components independantly
|
||||
|
||||
```javascript
|
||||
import { QrcodeStream, QrcodeDropZone, QrcodeCapture } from 'vue-qrcode-reader'
|
||||
|
||||
const MyComponent = {
|
||||
//
|
||||
components: {
|
||||
QrcodeStream,
|
||||
QrcodeDropZone,
|
||||
QrcodeCapture
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
or register all of them globally right away
|
||||
|
||||
```javascript
|
||||
import Vue from 'vue'
|
||||
import VueQrcodeReader from 'vue-qrcode-reader'
|
||||
|
||||
Vue.use(VueQrcodeReader)
|
||||
```
|
||||
|
||||
## Without NPM
|
||||
|
||||
Include the following JS file:
|
||||
|
||||
https://unpkg.com/vue-qrcode-reader/dist/vue-qrcode-reader.umd.js
|
||||
|
||||
Make sure to include it after Vue:
|
||||
|
||||
```html
|
||||
<script src="./vue.js"></script>
|
||||
<script src="./vue-qrcode-reader.umd.js"></script>
|
||||
```
|
||||
|
||||
All components are automatically registered globally.
|
||||
Use kebab-case to reference them in your templates:
|
||||
|
||||
```html
|
||||
<qrcode-stream></qrcode-stream>
|
||||
<qrcode-drop-zone></qrcode-drop-zone>
|
||||
<qrcode-capture></qrcode-capture>
|
||||
```
|
||||
|
||||
# Troubleshooting :zap:
|
||||
|
||||
#### I don't see the camera when using `QrcodeStream`.
|
||||
|
||||
- Check if it works on the demo page. Especially the [Handle Errors](https://gruhn.github.io/vue-qrcode-reader/demos/HandleErrors.html) demo,
|
||||
since it renders error messages.
|
||||
- The demo works but it doesn't work in my project: Listen for the `error` event to investigate errors.
|
||||
- The demo doesn't work: Carefully review the Browser Support section above.
|
||||
Maybe your device is just not supported.
|
||||
|
||||
#### I'm running a dev server on localhost. How to test on my mobile device without HTTPS?
|
||||
|
||||
- If your setup is Desktop Chrome + Android Chrome, use [Remote Debugging](https://developers.google.com/web/tools/chrome-devtools/remote-debugging/) which allows your Android device to [access your local server as localhost](https://developers.google.com/web/tools/chrome-devtools/remote-debugging/local-server).
|
||||
- Otherwise use a reverse proxy like [ngrok](https://ngrok.com/) or [serveo](https://serveo.net/) to temporarily make your local server publicly available with HTTPS.
|
||||
- There are also loads of serverless/static hosting services that have HTTPS enabled by default and where you can deploy your web app for free (e.g. _GitHub Pages_, _GitLab Pages_, _Google Firebase_, _Netlify_, _Heroku_, _ZEIT Now_, ...)
|
||||
|
||||
#### Some of my QR codes are not being detected.
|
||||
|
||||
- Make sure, there is some white border around the QR code.
|
||||
- Test your QR codes in the upstream packages: [`barcode-detector`](https://github.com/Sec-ant/barcode-detector) -> [`zxing-wasm`](https://github.com/Sec-ant/zxing-wasm) -> [`zxing-cpp`](https://github.com/zxing-cpp/zxing-cpp), and file detection issues in the highest-level repository where the problem first occurs.
|
||||
|
||||
#### 1D barcodes are not being detected.
|
||||
|
||||
The default value for the `formats` prop is `"['qr_code']"`, which reflects the setting before the `formats` prop was available.
|
||||
You'll need to add [other barcode formats](https://github.com/Sec-ant/barcode-detector?tab=readme-ov-file#barcode-detector) to this prop to detect those types of barcodes.
|
||||
Check out [this demo](https://gruhn.github.io/vue-qrcode-reader/demos/FullDemo.html).
|
||||
|
||||
#### How to make it work with Vue 2?
|
||||
|
||||
Support is dropped but you can downgrade to vue-qrcode-reader v3.\* or lower.
|
||||
|
||||
#### I get a "Failed to fetch" error at runtime for some Wasm file.
|
||||
|
||||
That Wasm file implements the QR code detector.
|
||||
Unfortunately, it's not very convenient to bundle this file with the package.
|
||||
So by default we fetch it at runtime from a CDN.
|
||||
That's an issue for offline applications or applications that run in a network with strict CSP policy.
|
||||
For a workaround see: https://github.com/gruhn/vue-qrcode-reader/issues/354
|
||||
|
||||
#### `torch` is not supported on my device, although it has a flashlight.
|
||||
|
||||
Support for `torch` is inconsistent across devices, cameras and browsers and operating systems.
|
||||
On some devices the rear camera supports `torch` but the front camera doesn't,
|
||||
even if the front camera actually has a flashlight.
|
||||
|
||||
Furthermore, `torch` is not supported on iOS at all (last checked iOS 17.1).
|
||||
|
||||
Visit [this page](https://gruhn.github.io/vue-qrcode-reader/select-camera-demo.html) with your device.
|
||||
The list of links represents all cameras installed on the device.
|
||||
If you click, the camera should be loaded.
|
||||
Below the camera view the JSON object of "capabilities" is printed.
|
||||
If it doesn't contain the key/value pair `"torch": true` then flashlight is not supported for that camera.
|
||||
|
||||
This JSON object provided as payload of the [`camera-on` event](https://gruhn.github.io/vue-qrcode-reader/api/QrcodeStream.html#camera-on).
|
20
node_modules/vue-qrcode-reader/dist/components/QrcodeCapture.vue.d.ts
generated
vendored
Normal file
20
node_modules/vue-qrcode-reader/dist/components/QrcodeCapture.vue.d.ts
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
import { type PropType } from 'vue';
|
||||
import { type BarcodeFormat, type DetectedBarcode } from 'barcode-detector/pure';
|
||||
declare const _default: import("vue").DefineComponent<{
|
||||
formats: {
|
||||
type: PropType<BarcodeFormat[]>;
|
||||
default: () => BarcodeFormat[];
|
||||
};
|
||||
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
||||
detect: (detectedCodes: DetectedBarcode[]) => void;
|
||||
}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
||||
formats: {
|
||||
type: PropType<BarcodeFormat[]>;
|
||||
default: () => BarcodeFormat[];
|
||||
};
|
||||
}>> & {
|
||||
onDetect?: (detectedCodes: DetectedBarcode[]) => any;
|
||||
}, {
|
||||
formats: ("aztec" | "code_128" | "code_39" | "code_93" | "codabar" | "databar" | "databar_expanded" | "data_matrix" | "dx_film_edge" | "ean_13" | "ean_8" | "itf" | "maxi_code" | "micro_qr_code" | "pdf417" | "qr_code" | "rm_qr_code" | "upc_a" | "upc_e" | "linear_codes" | "matrix_codes" | "unknown")[];
|
||||
}, {}>;
|
||||
export default _default;
|
33
node_modules/vue-qrcode-reader/dist/components/QrcodeDropZone.vue.d.ts
generated
vendored
Normal file
33
node_modules/vue-qrcode-reader/dist/components/QrcodeDropZone.vue.d.ts
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
import { type PropType } from 'vue';
|
||||
import { type BarcodeFormat, type DetectedBarcode } from 'barcode-detector/pure';
|
||||
declare function __VLS_template(): {
|
||||
default?(_: {}): any;
|
||||
};
|
||||
declare const __VLS_component: import("vue").DefineComponent<{
|
||||
formats: {
|
||||
type: PropType<BarcodeFormat[]>;
|
||||
default: () => BarcodeFormat[];
|
||||
};
|
||||
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
||||
detect: (detectedCodes: DetectedBarcode[]) => void;
|
||||
dragover: (isDraggingOver: boolean) => void;
|
||||
error: (error: EmmitedError) => void;
|
||||
}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
||||
formats: {
|
||||
type: PropType<BarcodeFormat[]>;
|
||||
default: () => BarcodeFormat[];
|
||||
};
|
||||
}>> & {
|
||||
onError?: (error: EmmitedError) => any;
|
||||
onDetect?: (detectedCodes: DetectedBarcode[]) => any;
|
||||
onDragover?: (isDraggingOver: boolean) => any;
|
||||
}, {
|
||||
formats: ("aztec" | "code_128" | "code_39" | "code_93" | "codabar" | "databar" | "databar_expanded" | "data_matrix" | "dx_film_edge" | "ean_13" | "ean_8" | "itf" | "maxi_code" | "micro_qr_code" | "pdf417" | "qr_code" | "rm_qr_code" | "upc_a" | "upc_e" | "linear_codes" | "matrix_codes" | "unknown")[];
|
||||
}, {}>;
|
||||
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
|
||||
export default _default;
|
||||
type __VLS_WithTemplateSlots<T, S> = T & {
|
||||
new (): {
|
||||
$slots: S;
|
||||
};
|
||||
};
|
98
node_modules/vue-qrcode-reader/dist/components/QrcodeStream.vue.d.ts
generated
vendored
Normal file
98
node_modules/vue-qrcode-reader/dist/components/QrcodeStream.vue.d.ts
generated
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
import type { DetectedBarcode, BarcodeFormat } from 'barcode-detector/pure';
|
||||
import { type PropType } from 'vue';
|
||||
declare function __VLS_template(): {
|
||||
default?(_: {}): any;
|
||||
};
|
||||
declare const __VLS_component: import("vue").DefineComponent<{
|
||||
/**
|
||||
* Passes an object with various camera configuration options.
|
||||
*/
|
||||
constraints: {
|
||||
type: PropType<MediaTrackConstraints>;
|
||||
default(): MediaTrackConstraints;
|
||||
};
|
||||
/**
|
||||
* Passes formats that will be recognized during detection.
|
||||
*/
|
||||
formats: {
|
||||
type: PropType<BarcodeFormat[]>;
|
||||
default: () => BarcodeFormat[];
|
||||
};
|
||||
/**
|
||||
* Setting this prop to true freezes the camera. Set to false to resume.
|
||||
*/
|
||||
paused: {
|
||||
type: BooleanConstructor;
|
||||
default: boolean;
|
||||
};
|
||||
/**
|
||||
* Enables or disables camera torch during detection.
|
||||
*/
|
||||
torch: {
|
||||
type: BooleanConstructor;
|
||||
default: boolean;
|
||||
};
|
||||
/**
|
||||
* Defines callback function that will be responsible for drawing detected code tracking rectangle
|
||||
*/
|
||||
track: {
|
||||
type: PropType<(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D | null) => void>;
|
||||
};
|
||||
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
||||
detect: (detectedCodes: DetectedBarcode[]) => void;
|
||||
"camera-on": (capabilities: Partial<MediaTrackCapabilities>) => void;
|
||||
"camera-off": () => void;
|
||||
error: (error: EmmitedError) => void;
|
||||
}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
|
||||
/**
|
||||
* Passes an object with various camera configuration options.
|
||||
*/
|
||||
constraints: {
|
||||
type: PropType<MediaTrackConstraints>;
|
||||
default(): MediaTrackConstraints;
|
||||
};
|
||||
/**
|
||||
* Passes formats that will be recognized during detection.
|
||||
*/
|
||||
formats: {
|
||||
type: PropType<BarcodeFormat[]>;
|
||||
default: () => BarcodeFormat[];
|
||||
};
|
||||
/**
|
||||
* Setting this prop to true freezes the camera. Set to false to resume.
|
||||
*/
|
||||
paused: {
|
||||
type: BooleanConstructor;
|
||||
default: boolean;
|
||||
};
|
||||
/**
|
||||
* Enables or disables camera torch during detection.
|
||||
*/
|
||||
torch: {
|
||||
type: BooleanConstructor;
|
||||
default: boolean;
|
||||
};
|
||||
/**
|
||||
* Defines callback function that will be responsible for drawing detected code tracking rectangle
|
||||
*/
|
||||
track: {
|
||||
type: PropType<(detectedCodes: DetectedBarcode[], ctx: CanvasRenderingContext2D | null) => void>;
|
||||
};
|
||||
}>> & {
|
||||
onError?: (error: EmmitedError) => any;
|
||||
onDetect?: (detectedCodes: DetectedBarcode[]) => any;
|
||||
"onCamera-on"?: (capabilities: Partial<MediaTrackCapabilities>) => any;
|
||||
"onCamera-off"?: () => any;
|
||||
}, {
|
||||
formats: ("aztec" | "code_128" | "code_39" | "code_93" | "codabar" | "databar" | "databar_expanded" | "data_matrix" | "dx_film_edge" | "ean_13" | "ean_8" | "itf" | "maxi_code" | "micro_qr_code" | "pdf417" | "qr_code" | "rm_qr_code" | "upc_a" | "upc_e" | "linear_codes" | "matrix_codes" | "unknown")[];
|
||||
torch: boolean;
|
||||
constraints: MediaTrackConstraints;
|
||||
paused: boolean;
|
||||
}, {}>;
|
||||
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
|
||||
export default _default;
|
||||
type __VLS_WithTemplateSlots<T, S> = T & {
|
||||
new (): {
|
||||
$slots: S;
|
||||
};
|
||||
};
|
9
node_modules/vue-qrcode-reader/dist/index.d.ts
generated
vendored
Normal file
9
node_modules/vue-qrcode-reader/dist/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import type { App, Plugin } from 'vue';
|
||||
import QrcodeStream from './components/QrcodeStream.vue';
|
||||
import QrcodeCapture from './components/QrcodeCapture.vue';
|
||||
import QrcodeDropZone from './components/QrcodeDropZone.vue';
|
||||
export declare function install(app: App): void;
|
||||
export { QrcodeStream, QrcodeCapture, QrcodeDropZone };
|
||||
export { setZXingModuleOverrides, type BarcodeFormat } from 'barcode-detector/pure';
|
||||
declare const plugin: Plugin;
|
||||
export { plugin as VueQrcodeReader };
|
6
node_modules/vue-qrcode-reader/dist/misc/callforth.d.ts
generated
vendored
Normal file
6
node_modules/vue-qrcode-reader/dist/misc/callforth.d.ts
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
export declare const eventOn: (eventTarget: EventTarget, successEvent: string, errorEvent?: string) => Promise<Event>;
|
||||
export declare const timeout: (milliseconds: number) => Promise<unknown>;
|
||||
export declare const polling: (predicate: any, options: {
|
||||
maxTries: number;
|
||||
interval: number;
|
||||
}) => Promise<any>;
|
6
node_modules/vue-qrcode-reader/dist/misc/camera.d.ts
generated
vendored
Normal file
6
node_modules/vue-qrcode-reader/dist/misc/camera.d.ts
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
export declare function start(videoEl: HTMLVideoElement, { constraints, torch, restart }: {
|
||||
constraints: MediaTrackConstraints;
|
||||
torch: boolean;
|
||||
restart?: boolean;
|
||||
}): Promise<Partial<MediaTrackCapabilities>>;
|
||||
export declare function stop(): Promise<void>;
|
13
node_modules/vue-qrcode-reader/dist/misc/errors.d.ts
generated
vendored
Normal file
13
node_modules/vue-qrcode-reader/dist/misc/errors.d.ts
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
export declare class DropImageFetchError extends Error {
|
||||
constructor();
|
||||
}
|
||||
export declare class StreamApiNotSupportedError extends Error {
|
||||
constructor();
|
||||
}
|
||||
export declare class InsecureContextError extends Error {
|
||||
constructor();
|
||||
}
|
||||
export declare class StreamLoadTimeoutError extends Error {
|
||||
constructor();
|
||||
}
|
||||
export type EmmitedError = DropImageFetchError | StreamApiNotSupportedError | InsecureContextError | StreamLoadTimeoutError | Error;
|
26
node_modules/vue-qrcode-reader/dist/misc/scanner.d.ts
generated
vendored
Normal file
26
node_modules/vue-qrcode-reader/dist/misc/scanner.d.ts
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
import { type DetectedBarcode, type BarcodeFormat, BarcodeDetector } from 'barcode-detector/pure';
|
||||
declare global {
|
||||
interface Window {
|
||||
BarcodeDetector?: typeof BarcodeDetector;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Update the set of targeted barcode formats. In particular, this function
|
||||
* can be called during scanning and the camera stream doesn't have to be
|
||||
* interrupted.
|
||||
*/
|
||||
export declare function setScanningFormats(formats: BarcodeFormat[]): Promise<void>;
|
||||
type ScanHandler = (_: DetectedBarcode[]) => void;
|
||||
/**
|
||||
* Continuously extracts frames from camera stream and tries to read
|
||||
* potentially pictured QR codes.
|
||||
*/
|
||||
export declare const keepScanning: (videoElement: HTMLVideoElement, { detectHandler, locateHandler, minDelay, formats }: {
|
||||
detectHandler: ScanHandler;
|
||||
locateHandler: ScanHandler;
|
||||
minDelay: number;
|
||||
formats: BarcodeFormat[];
|
||||
}) => Promise<void>;
|
||||
export declare const processFile: (file: File, formats?: BarcodeFormat[]) => Promise<DetectedBarcode[]>;
|
||||
export declare const processUrl: (url: string, formats?: BarcodeFormat[]) => Promise<DetectedBarcode[]>;
|
||||
export {};
|
2
node_modules/vue-qrcode-reader/dist/misc/shimGetUserMedia.d.ts
generated
vendored
Normal file
2
node_modules/vue-qrcode-reader/dist/misc/shimGetUserMedia.d.ts
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
declare const _default: (...args: any[]) => void;
|
||||
export default _default;
|
29
node_modules/vue-qrcode-reader/dist/misc/util.d.ts
generated
vendored
Normal file
29
node_modules/vue-qrcode-reader/dist/misc/util.d.ts
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Takes a function `action` and returns a new function, that behaves
|
||||
* like action but when called a second time does nothing.
|
||||
*/
|
||||
export declare const idempotent: <T>(action: (x: any) => T) => (...args: any[]) => T;
|
||||
/**
|
||||
* Throws an error if the `condition` in the first argument is `false`.
|
||||
* This function is useful to make assumptions explicit. For example,
|
||||
* let's say we have a variable
|
||||
*
|
||||
* const value : string | undefined = ...
|
||||
*
|
||||
* but from the context we know that it can actually never be `undefined`.
|
||||
* We can access attributes of `value` with
|
||||
*
|
||||
* value?.length
|
||||
*
|
||||
* but if the assumption is actually broken, we can a silent error.
|
||||
* In contrast, with
|
||||
*
|
||||
* assert(value !== undefined, 'reason why we assume value always defined')
|
||||
* value.length // no type error
|
||||
*
|
||||
* We make the assumption explicit and force a laud error. Also the type
|
||||
* check can narrow the type of `value` to `string` after the `assert` and we
|
||||
* can access properties without type error.
|
||||
*/
|
||||
export declare function assert(condition: boolean, failureMessage?: string): asserts condition;
|
||||
export declare function assertNever(_witness: never): never;
|
3306
node_modules/vue-qrcode-reader/dist/vue-qrcode-reader.js
generated
vendored
Normal file
3306
node_modules/vue-qrcode-reader/dist/vue-qrcode-reader.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
node_modules/vue-qrcode-reader/dist/vue-qrcode-reader.umd.js
generated
vendored
Normal file
3
node_modules/vue-qrcode-reader/dist/vue-qrcode-reader.umd.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
77
node_modules/vue-qrcode-reader/package.json
generated
vendored
Normal file
77
node_modules/vue-qrcode-reader/package.json
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "vue-qrcode-reader",
|
||||
"version": "5.6.0",
|
||||
"description": "A set of Vue.js components for detecting and decoding QR codes.",
|
||||
"author": {
|
||||
"name": "Niklas Gruhn",
|
||||
"email": "niklas@gruhn.me"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"packageManager": "pnpm@8.3.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"docs:dev": "vitepress dev docs",
|
||||
"docs:build": "vitepress build docs",
|
||||
"docs:preview": "vitepress preview docs",
|
||||
"format": "prettier **/*.{vue,ts,json,md} --write --ignore-path .gitignore --ignore-path docs/.gitignore",
|
||||
"type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false",
|
||||
"prepack": "pnpm run build"
|
||||
},
|
||||
"main": "./dist/vue-qrcode-reader.js",
|
||||
"module": "./dist/vue-qrcode-reader.js",
|
||||
"unpkg": "./dist/vue-qrcode-reader.umd.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/vue-qrcode-reader.js",
|
||||
"require": "./dist/vue-qrcode-reader.umd.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
}
|
||||
},
|
||||
"types": "./dist/index.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"barcode-detector": "2.2.2",
|
||||
"webrtc-adapter": "8.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node20": "20.1.2",
|
||||
"@types/node": "20.10.5",
|
||||
"@types/w3c-image-capture": "1.0.10",
|
||||
"@vite-pwa/vitepress": "0.3.1",
|
||||
"@vitejs/plugin-vue": "4.5.2",
|
||||
"@vue/compiler-sfc": "3.3.13",
|
||||
"@vue/eslint-config-prettier": "8.0.0",
|
||||
"@vue/eslint-config-typescript": "12.0.0",
|
||||
"@vue/tsconfig": "0.5.1",
|
||||
"eslint": "8.56.0",
|
||||
"eslint-plugin-prettier": "5.1.0",
|
||||
"eslint-plugin-vue": "9.19.2",
|
||||
"prettier": "3.1.1",
|
||||
"semantic-release": "22.0.12",
|
||||
"typescript": "5.5.3",
|
||||
"vite": "5.0.10",
|
||||
"vite-plugin-dts": "3.6.4",
|
||||
"vitepress": "1.0.0-rc.32",
|
||||
"vue": "3.3.13",
|
||||
"vue-tsc": "1.8.25",
|
||||
"workbox-window": "7.0.0"
|
||||
},
|
||||
"bugs": "https://github.com/gruhn/vue-qrcode-reader/issues",
|
||||
"homepage": "https://gruhn.github.io/vue-qrcode-reader/",
|
||||
"keywords": [
|
||||
"vue",
|
||||
"vuejs",
|
||||
"vue-component",
|
||||
"qrcode",
|
||||
"qrcode-reader",
|
||||
"qrcode-scanner",
|
||||
"webrtc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"repository": "github:gruhn/vue-qrcode-reader"
|
||||
}
|
70
node_modules/webrtc-adapter/.eslintrc
generated
vendored
Normal file
70
node_modules/webrtc-adapter/.eslintrc
generated
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
{
|
||||
"rules": {
|
||||
"array-bracket-spacing": 2,
|
||||
"block-spacing": [2, "never"],
|
||||
"brace-style": [2, "1tbs", {"allowSingleLine": false}],
|
||||
"camelcase": [2, {"properties": "always"}],
|
||||
"curly": 2,
|
||||
"default-case": 2,
|
||||
"dot-notation": 2,
|
||||
"eqeqeq": 2,
|
||||
"id-match": ["error", "^[\x00-\x7F]+$", {
|
||||
"properties": true,
|
||||
"onlyDeclarations": false,
|
||||
"ignoreDestructuring": false
|
||||
}],
|
||||
"indent": [
|
||||
2,
|
||||
2,
|
||||
{"SwitchCase": 1}
|
||||
],
|
||||
"key-spacing": [2, {"beforeColon": false, "afterColon": true}],
|
||||
"keyword-spacing": 2,
|
||||
"max-len": [2, 80, 2, {"ignoreUrls": true}],
|
||||
"new-cap": [2, {"newIsCapExceptions": [
|
||||
"webkitRTCPeerConnection",
|
||||
"mozRTCPeerConnection"
|
||||
]}],
|
||||
"no-console": 0,
|
||||
"no-else-return": 2,
|
||||
"no-eval": 2,
|
||||
"no-multi-spaces": 2,
|
||||
"no-multiple-empty-lines": [2, {"max": 2}],
|
||||
"no-shadow": 2,
|
||||
"no-trailing-spaces": 2,
|
||||
"no-unused-expressions": 2,
|
||||
"no-unused-vars": [2, {"args": "none"}],
|
||||
"object-curly-spacing": [2, "never"],
|
||||
"padded-blocks": [2, "never"],
|
||||
"quotes": [
|
||||
2,
|
||||
"single"
|
||||
],
|
||||
"semi": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"space-before-blocks": 2,
|
||||
"space-before-function-paren": [2, "never"],
|
||||
"space-unary-ops": 2,
|
||||
"space-infix-ops": 2,
|
||||
"spaced-comment": 2,
|
||||
"valid-typeof": 2
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": ["eslint:recommended"],
|
||||
"parserOptions": {
|
||||
"sourceType": "module"
|
||||
},
|
||||
"globals": {
|
||||
"module": true,
|
||||
"require": true,
|
||||
"process": true,
|
||||
"Promise": true,
|
||||
"Map": true
|
||||
}
|
||||
}
|
65
node_modules/webrtc-adapter/.travis.yml
generated
vendored
Normal file
65
node_modules/webrtc-adapter/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
sudo: false
|
||||
language: node_js
|
||||
dist: trusty
|
||||
node_js:
|
||||
- "7"
|
||||
|
||||
env:
|
||||
- CXX=g++-4.8
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
sudo: false
|
||||
env: BROWSER=chrome BVER=stable
|
||||
- os: linux
|
||||
sudo: false
|
||||
env: BROWSER=chrome BVER=beta
|
||||
- os: linux
|
||||
sudo: false
|
||||
env: BROWSER=chrome BVER=unstable
|
||||
- os: linux
|
||||
sudo: false
|
||||
env: BROWSER=firefox BVER=stable
|
||||
- os: linux
|
||||
sudo: false
|
||||
env: BROWSER=firefox BVER=beta
|
||||
- os: linux
|
||||
sudo: false
|
||||
env: BROWSER=firefox BVER=unstable
|
||||
- os: osx
|
||||
sudo: required
|
||||
osx_image: xcode9.4
|
||||
env: BROWSER=safari BVER=stable
|
||||
- os: osx
|
||||
sudo: required
|
||||
osx_image: xcode11.2
|
||||
env: BROWSER=safari BVER=unstable
|
||||
|
||||
fast_finish: true
|
||||
|
||||
allow_failures:
|
||||
- os: linux
|
||||
sudo: false
|
||||
env: BROWSER=chrome BVER=unstable
|
||||
- os: linux
|
||||
sudo: false
|
||||
env: BROWSER=firefox BVER=unstable
|
||||
|
||||
before_script:
|
||||
- ./node_modules/travis-multirunner/setup.sh
|
||||
- export DISPLAY=:99.0
|
||||
- if [ -f /etc/init.d/xvfb ]; then sh -e /etc/init.d/xvfb start; fi
|
||||
|
||||
after_failure:
|
||||
- for file in *.log; do echo $file; echo "======================"; cat $file; done || true
|
||||
|
||||
notifications:
|
||||
email:
|
||||
-
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-4.8
|
15
node_modules/webrtc-adapter/CONTRIBUTING.md
generated
vendored
Normal file
15
node_modules/webrtc-adapter/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
WebRTC welcomes patches/pulls for features and bug fixes.
|
||||
|
||||
For contributors external to Google, follow the instructions given in the [Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual).
|
||||
|
||||
In all cases, contributors must sign a contributor license agreement before a contribution can be accepted. Please complete the agreement for an [individual](https://developers.google.com/open-source/cla/individual) or a [corporation](https://developers.google.com/open-source/cla/corporate) as appropriate.
|
||||
|
||||
If you plan to add a significant component or large chunk of code, we recommend you bring this up on the [webrtc-discuss group](https://groups.google.com/forum/#!forum/discuss-webrtc) for a design discussion before writing code.
|
||||
|
||||
If appropriate, write a unit test which demonstrates that your code functions as expected. Tests are the best way to ensure that future contributors do not break your code accidentally.
|
||||
|
||||
To request a change or addition, you must [submit a pull request](https://help.github.com/categories/collaborating/).
|
||||
|
||||
WebRTC developers monitor outstanding pull requests. They may request changes to the pull request before accepting. They will also verify that a CLA has been signed.
|
||||
|
||||
The [Developer's Guide](https://bit.ly/webrtcdevguide) for this repo has more detailed information about code style, structure and validation.
|
71
node_modules/webrtc-adapter/Gruntfile.js
generated
vendored
Normal file
71
node_modules/webrtc-adapter/Gruntfile.js
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function(grunt) {
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
babel: {
|
||||
options: {
|
||||
presets: ['@babel/preset-env']
|
||||
},
|
||||
dist: {
|
||||
files: [{
|
||||
expand: 'true',
|
||||
cwd: 'src/js',
|
||||
src: ['*.js', '**/*.js'],
|
||||
dest: 'dist/'
|
||||
}]
|
||||
}
|
||||
},
|
||||
browserify: {
|
||||
adapterGlobalObject: {
|
||||
src: ['./dist/adapter_core5.js'],
|
||||
dest: './out/adapter.js',
|
||||
options: {
|
||||
browserifyOptions: {
|
||||
// Exposes shim methods in a global object to the browser.
|
||||
// The tests require this.
|
||||
standalone: 'adapter'
|
||||
}
|
||||
}
|
||||
},
|
||||
// Use this if you do not want adapter to expose anything to the global
|
||||
// scope.
|
||||
adapterAndNoGlobalObject: {
|
||||
src: ['./dist/adapter_core5.js'],
|
||||
dest: './out/adapter_no_global.js'
|
||||
}
|
||||
},
|
||||
eslint: {
|
||||
options: {
|
||||
overrideConfigFile: '.eslintrc'
|
||||
},
|
||||
target: ['src/**/*.js', 'test/*.js', 'test/unit/*.js', 'test/e2e/*.js']
|
||||
},
|
||||
copy: {
|
||||
build: {
|
||||
dest: 'release/',
|
||||
cwd: 'out',
|
||||
src: '**',
|
||||
nonull: true,
|
||||
expand: true
|
||||
}
|
||||
},
|
||||
shell: {
|
||||
downloadBrowser : {
|
||||
command: 'BROWSER=${BROWSER-chrome} BVER=${BVER-stable} ./node_modules/travis-multirunner/setup.sh'
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
grunt.loadNpmTasks('grunt-eslint');
|
||||
grunt.loadNpmTasks('grunt-browserify');
|
||||
grunt.loadNpmTasks('grunt-babel');
|
||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||
grunt.loadNpmTasks('grunt-shell');
|
||||
|
||||
grunt.registerTask('default', ['eslint', 'build']);
|
||||
grunt.registerTask('lint', ['eslint']);
|
||||
grunt.registerTask('build', ['babel', 'browserify']);
|
||||
grunt.registerTask('copyForPublish', ['copy']);
|
||||
grunt.registerTask('downloadBrowser', ['shell:downloadBrowser'])
|
||||
};
|
30
node_modules/webrtc-adapter/LICENSE.md
generated
vendored
Normal file
30
node_modules/webrtc-adapter/LICENSE.md
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
Copyright (c) 2014, The WebRTC project authors. All rights reserved.
|
||||
Copyright (c) 2018, The adapter.js project authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of Google nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
79
node_modules/webrtc-adapter/README.md
generated
vendored
Normal file
79
node_modules/webrtc-adapter/README.md
generated
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
# WebRTC adapter #
|
||||
adapter.js is a shim to insulate apps from spec changes and prefix differences in WebRTC. The prefix differences are mostly gone these days but differences in behaviour between browsers remain.
|
||||
|
||||
This repository used to be part of the WebRTC organisation on github but moved. We aim to keep the old repository updated with new releases.
|
||||
|
||||
## Install ##
|
||||
|
||||
#### NPM
|
||||
```bash
|
||||
npm install webrtc-adapter
|
||||
```
|
||||
|
||||
#### Bower
|
||||
```bash
|
||||
bower install webrtc-adapter
|
||||
```
|
||||
|
||||
## Usage ##
|
||||
##### Javascript
|
||||
Just import adapter:
|
||||
```
|
||||
import adapter from 'webrtc-adapter';
|
||||
```
|
||||
No further action is required. You might want to use adapters browser detection
|
||||
which detects which webrtc quirks are required. You can look at
|
||||
```
|
||||
adapter.browserDetails.browser
|
||||
```
|
||||
for webrtc engine detection (which will for example detect Opera or the Chromium based Edge as 'chrome') and
|
||||
```
|
||||
adapter.browserDetails.version
|
||||
```
|
||||
for the version according to the user-agent string.
|
||||
|
||||
##### NPM
|
||||
Copy to desired location in your src tree or use a minify/vulcanize tool (node_modules is usually not published with the code).
|
||||
See [webrtc/samples repo](https://github.com/webrtc/samples) as an example on how you can do this.
|
||||
|
||||
#### Prebuilt releases
|
||||
##### Web
|
||||
In the [gh-pages branch](https://github.com/webrtcHacks/adapter/tree/gh-pages) prebuilt ready to use files can be downloaded/linked directly.
|
||||
Latest version can be found at https://webrtc.github.io/adapter/adapter-latest.js.
|
||||
Specific versions can be found at https://webrtc.github.io/adapter/adapter-N.N.N.js, e.g. https://webrtc.github.io/adapter/adapter-1.0.2.js.
|
||||
|
||||
##### Bower
|
||||
You will find `adapter.js` in `bower_components/webrtc-adapter/`.
|
||||
|
||||
##### NPM
|
||||
In node_modules/webrtc-adapter/out/ folder you will find 4 files:
|
||||
* `adapter.js` - includes all the shims and is visible in the browser under the global `adapter` object (window.adapter).
|
||||
* `adapter_no_global.js` - same as `adapter.js` but is not exposed/visible in the browser (you cannot call/interact with the shims in the browser).
|
||||
|
||||
Include the file that suits your need in your project.
|
||||
|
||||
## Development ##
|
||||
Head over to [test/README.md](https://github.com/webrtcHacks/adapter/blob/master/test/README.md) and get started developing.
|
||||
|
||||
## Publish a new version ##
|
||||
* Go to the adapter repository root directory
|
||||
* Make sure your repository is clean, i.e. no untracked files etc. Also check that you are on the master branch and have pulled the latest changes.
|
||||
* Depending on the impact of the release, either use `patch`, `minor` or `major` in place of `<version>`. Run `npm version <version> -m 'bump to %s'` and type in your password lots of times (setting up credential caching is probably a good idea).
|
||||
* Create and merge the PR if green in the GitHub web ui
|
||||
* Go to the releases tab in the GitHub web ui and edit the tag.
|
||||
* Add a summary of the recent commits in the tag summary and a link to the diff between the previous and current version in the description, [example](https://github.com/webrtcHacks/adapter/releases/tag/v3.4.1).
|
||||
* Go back to your checkout and run `git pull`
|
||||
* Run `npm publish` (you need access to the [webrtc-adapter npmjs package](https://www.npmjs.com/package/webrtc-adapter)). For big changes, consider using a [tag version](https://docs.npmjs.com/adding-dist-tags-to-packages) such as `next` and then [change the dist-tag after testing](https://docs.npmjs.com/cli/dist-tag).
|
||||
* Done! There should now be a new release published to NPM and the gh-pages branch.
|
||||
|
||||
Note: Currently only tested on Linux, not sure about Mac but will definitely not work on Windows.
|
||||
|
||||
### Publish a hotfix patch versions
|
||||
In some cases it may be necessary to do a patch version while there are significant changes changes on the master branch.
|
||||
To make a patch release,
|
||||
* checkout the latest git tag using `git checkout tags/vMajor.minor.patch`.
|
||||
* checkout a new branch, using a name such as patchrelease-major-minor-patch.
|
||||
* cherry-pick the fixes using `git cherry-pick some-commit-hash`.
|
||||
* run `npm version patch`. This will create a new patch version and publish it on github.
|
||||
* check out `origin/bumpVersion` branch and publish the new version using `npm publish`.
|
||||
* the branch can now safely be deleted. It is not necessary to merge it into the main branch since it only contains cherry-picked commits.
|
25
node_modules/webrtc-adapter/bower.json
generated
vendored
Normal file
25
node_modules/webrtc-adapter/bower.json
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "webrtc-adapter",
|
||||
"description": "A shim to insulate apps from WebRTC spec changes and browser prefix differences",
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "./release/adapter.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webrtchacks/adapter.git"
|
||||
},
|
||||
"authors": [
|
||||
"The WebRTC project authors (https://www.webrtc.org/)",
|
||||
"The adapter.js project authors (https://github.com/webrtchacks/adapter/)"
|
||||
],
|
||||
"moduleType": [
|
||||
"node"
|
||||
],
|
||||
"ignore": [
|
||||
"test/*"
|
||||
],
|
||||
"keywords": [
|
||||
"WebRTC",
|
||||
"RTCPeerConnection",
|
||||
"getUserMedia"
|
||||
]
|
||||
}
|
21
node_modules/webrtc-adapter/dist/adapter_core.js
generated
vendored
Normal file
21
node_modules/webrtc-adapter/dist/adapter_core.js
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports["default"] = void 0;
|
||||
var _adapter_factory = require("./adapter_factory.js");
|
||||
var adapter = (0, _adapter_factory.adapterFactory)({
|
||||
window: typeof window === 'undefined' ? undefined : window
|
||||
});
|
||||
var _default = adapter;
|
||||
exports["default"] = _default;
|
16
node_modules/webrtc-adapter/dist/adapter_core5.js
generated
vendored
Normal file
16
node_modules/webrtc-adapter/dist/adapter_core5.js
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
|
||||
'use strict';
|
||||
|
||||
var _adapter_factory = require("./adapter_factory.js");
|
||||
var adapter = (0, _adapter_factory.adapterFactory)({
|
||||
window: typeof window === 'undefined' ? undefined : window
|
||||
});
|
||||
module.exports = adapter; // this is the difference from adapter_core.
|
141
node_modules/webrtc-adapter/dist/adapter_factory.js
generated
vendored
Normal file
141
node_modules/webrtc-adapter/dist/adapter_factory.js
generated
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
"use strict";
|
||||
|
||||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.adapterFactory = adapterFactory;
|
||||
var utils = _interopRequireWildcard(require("./utils"));
|
||||
var chromeShim = _interopRequireWildcard(require("./chrome/chrome_shim"));
|
||||
var firefoxShim = _interopRequireWildcard(require("./firefox/firefox_shim"));
|
||||
var safariShim = _interopRequireWildcard(require("./safari/safari_shim"));
|
||||
var commonShim = _interopRequireWildcard(require("./common_shim"));
|
||||
var sdp = _interopRequireWildcard(require("sdp"));
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
|
||||
// Browser shims.
|
||||
|
||||
// Shimming starts here.
|
||||
function adapterFactory() {
|
||||
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
||||
window = _ref.window;
|
||||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
||||
shimChrome: true,
|
||||
shimFirefox: true,
|
||||
shimSafari: true
|
||||
};
|
||||
// Utils.
|
||||
var logging = utils.log;
|
||||
var browserDetails = utils.detectBrowser(window);
|
||||
var adapter = {
|
||||
browserDetails: browserDetails,
|
||||
commonShim: commonShim,
|
||||
extractVersion: utils.extractVersion,
|
||||
disableLog: utils.disableLog,
|
||||
disableWarnings: utils.disableWarnings,
|
||||
// Expose sdp as a convenience. For production apps include directly.
|
||||
sdp: sdp
|
||||
};
|
||||
|
||||
// Shim browser if found.
|
||||
switch (browserDetails.browser) {
|
||||
case 'chrome':
|
||||
if (!chromeShim || !chromeShim.shimPeerConnection || !options.shimChrome) {
|
||||
logging('Chrome shim is not included in this adapter release.');
|
||||
return adapter;
|
||||
}
|
||||
if (browserDetails.version === null) {
|
||||
logging('Chrome shim can not determine version, not shimming.');
|
||||
return adapter;
|
||||
}
|
||||
logging('adapter.js shimming chrome.');
|
||||
// Export to the adapter global object visible in the browser.
|
||||
adapter.browserShim = chromeShim;
|
||||
|
||||
// Must be called before shimPeerConnection.
|
||||
commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails);
|
||||
commonShim.shimParameterlessSetLocalDescription(window, browserDetails);
|
||||
chromeShim.shimGetUserMedia(window, browserDetails);
|
||||
chromeShim.shimMediaStream(window, browserDetails);
|
||||
chromeShim.shimPeerConnection(window, browserDetails);
|
||||
chromeShim.shimOnTrack(window, browserDetails);
|
||||
chromeShim.shimAddTrackRemoveTrack(window, browserDetails);
|
||||
chromeShim.shimGetSendersWithDtmf(window, browserDetails);
|
||||
chromeShim.shimGetStats(window, browserDetails);
|
||||
chromeShim.shimSenderReceiverGetStats(window, browserDetails);
|
||||
chromeShim.fixNegotiationNeeded(window, browserDetails);
|
||||
commonShim.shimRTCIceCandidate(window, browserDetails);
|
||||
commonShim.shimRTCIceCandidateRelayProtocol(window, browserDetails);
|
||||
commonShim.shimConnectionState(window, browserDetails);
|
||||
commonShim.shimMaxMessageSize(window, browserDetails);
|
||||
commonShim.shimSendThrowTypeError(window, browserDetails);
|
||||
commonShim.removeExtmapAllowMixed(window, browserDetails);
|
||||
break;
|
||||
case 'firefox':
|
||||
if (!firefoxShim || !firefoxShim.shimPeerConnection || !options.shimFirefox) {
|
||||
logging('Firefox shim is not included in this adapter release.');
|
||||
return adapter;
|
||||
}
|
||||
logging('adapter.js shimming firefox.');
|
||||
// Export to the adapter global object visible in the browser.
|
||||
adapter.browserShim = firefoxShim;
|
||||
|
||||
// Must be called before shimPeerConnection.
|
||||
commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails);
|
||||
commonShim.shimParameterlessSetLocalDescription(window, browserDetails);
|
||||
firefoxShim.shimGetUserMedia(window, browserDetails);
|
||||
firefoxShim.shimPeerConnection(window, browserDetails);
|
||||
firefoxShim.shimOnTrack(window, browserDetails);
|
||||
firefoxShim.shimRemoveStream(window, browserDetails);
|
||||
firefoxShim.shimSenderGetStats(window, browserDetails);
|
||||
firefoxShim.shimReceiverGetStats(window, browserDetails);
|
||||
firefoxShim.shimRTCDataChannel(window, browserDetails);
|
||||
firefoxShim.shimAddTransceiver(window, browserDetails);
|
||||
firefoxShim.shimGetParameters(window, browserDetails);
|
||||
firefoxShim.shimCreateOffer(window, browserDetails);
|
||||
firefoxShim.shimCreateAnswer(window, browserDetails);
|
||||
commonShim.shimRTCIceCandidate(window, browserDetails);
|
||||
commonShim.shimConnectionState(window, browserDetails);
|
||||
commonShim.shimMaxMessageSize(window, browserDetails);
|
||||
commonShim.shimSendThrowTypeError(window, browserDetails);
|
||||
break;
|
||||
case 'safari':
|
||||
if (!safariShim || !options.shimSafari) {
|
||||
logging('Safari shim is not included in this adapter release.');
|
||||
return adapter;
|
||||
}
|
||||
logging('adapter.js shimming safari.');
|
||||
// Export to the adapter global object visible in the browser.
|
||||
adapter.browserShim = safariShim;
|
||||
|
||||
// Must be called before shimCallbackAPI.
|
||||
commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails);
|
||||
commonShim.shimParameterlessSetLocalDescription(window, browserDetails);
|
||||
safariShim.shimRTCIceServerUrls(window, browserDetails);
|
||||
safariShim.shimCreateOfferLegacy(window, browserDetails);
|
||||
safariShim.shimCallbacksAPI(window, browserDetails);
|
||||
safariShim.shimLocalStreamsAPI(window, browserDetails);
|
||||
safariShim.shimRemoteStreamsAPI(window, browserDetails);
|
||||
safariShim.shimTrackEventTransceiver(window, browserDetails);
|
||||
safariShim.shimGetUserMedia(window, browserDetails);
|
||||
safariShim.shimAudioContext(window, browserDetails);
|
||||
commonShim.shimRTCIceCandidate(window, browserDetails);
|
||||
commonShim.shimRTCIceCandidateRelayProtocol(window, browserDetails);
|
||||
commonShim.shimMaxMessageSize(window, browserDetails);
|
||||
commonShim.shimSendThrowTypeError(window, browserDetails);
|
||||
commonShim.removeExtmapAllowMixed(window, browserDetails);
|
||||
break;
|
||||
default:
|
||||
logging('Unsupported browser!');
|
||||
break;
|
||||
}
|
||||
return adapter;
|
||||
}
|
698
node_modules/webrtc-adapter/dist/chrome/chrome_shim.js
generated
vendored
Normal file
698
node_modules/webrtc-adapter/dist/chrome/chrome_shim.js
generated
vendored
Normal file
@ -0,0 +1,698 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.fixNegotiationNeeded = fixNegotiationNeeded;
|
||||
exports.shimAddTrackRemoveTrack = shimAddTrackRemoveTrack;
|
||||
exports.shimAddTrackRemoveTrackWithNative = shimAddTrackRemoveTrackWithNative;
|
||||
Object.defineProperty(exports, "shimGetDisplayMedia", {
|
||||
enumerable: true,
|
||||
get: function get() {
|
||||
return _getdisplaymedia.shimGetDisplayMedia;
|
||||
}
|
||||
});
|
||||
exports.shimGetSendersWithDtmf = shimGetSendersWithDtmf;
|
||||
exports.shimGetStats = shimGetStats;
|
||||
Object.defineProperty(exports, "shimGetUserMedia", {
|
||||
enumerable: true,
|
||||
get: function get() {
|
||||
return _getusermedia.shimGetUserMedia;
|
||||
}
|
||||
});
|
||||
exports.shimMediaStream = shimMediaStream;
|
||||
exports.shimOnTrack = shimOnTrack;
|
||||
exports.shimPeerConnection = shimPeerConnection;
|
||||
exports.shimSenderReceiverGetStats = shimSenderReceiverGetStats;
|
||||
var utils = _interopRequireWildcard(require("../utils.js"));
|
||||
var _getusermedia = require("./getusermedia");
|
||||
var _getdisplaymedia = require("./getdisplaymedia");
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
|
||||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
||||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
||||
function shimMediaStream(window) {
|
||||
window.MediaStream = window.MediaStream || window.webkitMediaStream;
|
||||
}
|
||||
function shimOnTrack(window) {
|
||||
if (_typeof(window) === 'object' && window.RTCPeerConnection && !('ontrack' in window.RTCPeerConnection.prototype)) {
|
||||
Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', {
|
||||
get: function get() {
|
||||
return this._ontrack;
|
||||
},
|
||||
set: function set(f) {
|
||||
if (this._ontrack) {
|
||||
this.removeEventListener('track', this._ontrack);
|
||||
}
|
||||
this.addEventListener('track', this._ontrack = f);
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription;
|
||||
window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() {
|
||||
var _this = this;
|
||||
if (!this._ontrackpoly) {
|
||||
this._ontrackpoly = function (e) {
|
||||
// onaddstream does not fire when a track is added to an existing
|
||||
// stream. But stream.onaddtrack is implemented so we use that.
|
||||
e.stream.addEventListener('addtrack', function (te) {
|
||||
var receiver;
|
||||
if (window.RTCPeerConnection.prototype.getReceivers) {
|
||||
receiver = _this.getReceivers().find(function (r) {
|
||||
return r.track && r.track.id === te.track.id;
|
||||
});
|
||||
} else {
|
||||
receiver = {
|
||||
track: te.track
|
||||
};
|
||||
}
|
||||
var event = new Event('track');
|
||||
event.track = te.track;
|
||||
event.receiver = receiver;
|
||||
event.transceiver = {
|
||||
receiver: receiver
|
||||
};
|
||||
event.streams = [e.stream];
|
||||
_this.dispatchEvent(event);
|
||||
});
|
||||
e.stream.getTracks().forEach(function (track) {
|
||||
var receiver;
|
||||
if (window.RTCPeerConnection.prototype.getReceivers) {
|
||||
receiver = _this.getReceivers().find(function (r) {
|
||||
return r.track && r.track.id === track.id;
|
||||
});
|
||||
} else {
|
||||
receiver = {
|
||||
track: track
|
||||
};
|
||||
}
|
||||
var event = new Event('track');
|
||||
event.track = track;
|
||||
event.receiver = receiver;
|
||||
event.transceiver = {
|
||||
receiver: receiver
|
||||
};
|
||||
event.streams = [e.stream];
|
||||
_this.dispatchEvent(event);
|
||||
});
|
||||
};
|
||||
this.addEventListener('addstream', this._ontrackpoly);
|
||||
}
|
||||
return origSetRemoteDescription.apply(this, arguments);
|
||||
};
|
||||
} else {
|
||||
// even if RTCRtpTransceiver is in window, it is only used and
|
||||
// emitted in unified-plan. Unfortunately this means we need
|
||||
// to unconditionally wrap the event.
|
||||
utils.wrapPeerConnectionEvent(window, 'track', function (e) {
|
||||
if (!e.transceiver) {
|
||||
Object.defineProperty(e, 'transceiver', {
|
||||
value: {
|
||||
receiver: e.receiver
|
||||
}
|
||||
});
|
||||
}
|
||||
return e;
|
||||
});
|
||||
}
|
||||
}
|
||||
function shimGetSendersWithDtmf(window) {
|
||||
// Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack.
|
||||
if (_typeof(window) === 'object' && window.RTCPeerConnection && !('getSenders' in window.RTCPeerConnection.prototype) && 'createDTMFSender' in window.RTCPeerConnection.prototype) {
|
||||
var shimSenderWithDtmf = function shimSenderWithDtmf(pc, track) {
|
||||
return {
|
||||
track: track,
|
||||
get dtmf() {
|
||||
if (this._dtmf === undefined) {
|
||||
if (track.kind === 'audio') {
|
||||
this._dtmf = pc.createDTMFSender(track);
|
||||
} else {
|
||||
this._dtmf = null;
|
||||
}
|
||||
}
|
||||
return this._dtmf;
|
||||
},
|
||||
_pc: pc
|
||||
};
|
||||
};
|
||||
|
||||
// augment addTrack when getSenders is not available.
|
||||
if (!window.RTCPeerConnection.prototype.getSenders) {
|
||||
window.RTCPeerConnection.prototype.getSenders = function getSenders() {
|
||||
this._senders = this._senders || [];
|
||||
return this._senders.slice(); // return a copy of the internal state.
|
||||
};
|
||||
|
||||
var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
|
||||
window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) {
|
||||
var sender = origAddTrack.apply(this, arguments);
|
||||
if (!sender) {
|
||||
sender = shimSenderWithDtmf(this, track);
|
||||
this._senders.push(sender);
|
||||
}
|
||||
return sender;
|
||||
};
|
||||
var origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;
|
||||
window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) {
|
||||
origRemoveTrack.apply(this, arguments);
|
||||
var idx = this._senders.indexOf(sender);
|
||||
if (idx !== -1) {
|
||||
this._senders.splice(idx, 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
var origAddStream = window.RTCPeerConnection.prototype.addStream;
|
||||
window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
|
||||
var _this2 = this;
|
||||
this._senders = this._senders || [];
|
||||
origAddStream.apply(this, [stream]);
|
||||
stream.getTracks().forEach(function (track) {
|
||||
_this2._senders.push(shimSenderWithDtmf(_this2, track));
|
||||
});
|
||||
};
|
||||
var origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
|
||||
window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
|
||||
var _this3 = this;
|
||||
this._senders = this._senders || [];
|
||||
origRemoveStream.apply(this, [stream]);
|
||||
stream.getTracks().forEach(function (track) {
|
||||
var sender = _this3._senders.find(function (s) {
|
||||
return s.track === track;
|
||||
});
|
||||
if (sender) {
|
||||
// remove sender
|
||||
_this3._senders.splice(_this3._senders.indexOf(sender), 1);
|
||||
}
|
||||
});
|
||||
};
|
||||
} else if (_typeof(window) === 'object' && window.RTCPeerConnection && 'getSenders' in window.RTCPeerConnection.prototype && 'createDTMFSender' in window.RTCPeerConnection.prototype && window.RTCRtpSender && !('dtmf' in window.RTCRtpSender.prototype)) {
|
||||
var origGetSenders = window.RTCPeerConnection.prototype.getSenders;
|
||||
window.RTCPeerConnection.prototype.getSenders = function getSenders() {
|
||||
var _this4 = this;
|
||||
var senders = origGetSenders.apply(this, []);
|
||||
senders.forEach(function (sender) {
|
||||
return sender._pc = _this4;
|
||||
});
|
||||
return senders;
|
||||
};
|
||||
Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', {
|
||||
get: function get() {
|
||||
if (this._dtmf === undefined) {
|
||||
if (this.track.kind === 'audio') {
|
||||
this._dtmf = this._pc.createDTMFSender(this.track);
|
||||
} else {
|
||||
this._dtmf = null;
|
||||
}
|
||||
}
|
||||
return this._dtmf;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
function shimGetStats(window) {
|
||||
if (!window.RTCPeerConnection) {
|
||||
return;
|
||||
}
|
||||
var origGetStats = window.RTCPeerConnection.prototype.getStats;
|
||||
window.RTCPeerConnection.prototype.getStats = function getStats() {
|
||||
var _this5 = this;
|
||||
var _arguments = Array.prototype.slice.call(arguments),
|
||||
selector = _arguments[0],
|
||||
onSucc = _arguments[1],
|
||||
onErr = _arguments[2];
|
||||
|
||||
// If selector is a function then we are in the old style stats so just
|
||||
// pass back the original getStats format to avoid breaking old users.
|
||||
if (arguments.length > 0 && typeof selector === 'function') {
|
||||
return origGetStats.apply(this, arguments);
|
||||
}
|
||||
|
||||
// When spec-style getStats is supported, return those when called with
|
||||
// either no arguments or the selector argument is null.
|
||||
if (origGetStats.length === 0 && (arguments.length === 0 || typeof selector !== 'function')) {
|
||||
return origGetStats.apply(this, []);
|
||||
}
|
||||
var fixChromeStats_ = function fixChromeStats_(response) {
|
||||
var standardReport = {};
|
||||
var reports = response.result();
|
||||
reports.forEach(function (report) {
|
||||
var standardStats = {
|
||||
id: report.id,
|
||||
timestamp: report.timestamp,
|
||||
type: {
|
||||
localcandidate: 'local-candidate',
|
||||
remotecandidate: 'remote-candidate'
|
||||
}[report.type] || report.type
|
||||
};
|
||||
report.names().forEach(function (name) {
|
||||
standardStats[name] = report.stat(name);
|
||||
});
|
||||
standardReport[standardStats.id] = standardStats;
|
||||
});
|
||||
return standardReport;
|
||||
};
|
||||
|
||||
// shim getStats with maplike support
|
||||
var makeMapStats = function makeMapStats(stats) {
|
||||
return new Map(Object.keys(stats).map(function (key) {
|
||||
return [key, stats[key]];
|
||||
}));
|
||||
};
|
||||
if (arguments.length >= 2) {
|
||||
var successCallbackWrapper_ = function successCallbackWrapper_(response) {
|
||||
onSucc(makeMapStats(fixChromeStats_(response)));
|
||||
};
|
||||
return origGetStats.apply(this, [successCallbackWrapper_, selector]);
|
||||
}
|
||||
|
||||
// promise-support
|
||||
return new Promise(function (resolve, reject) {
|
||||
origGetStats.apply(_this5, [function (response) {
|
||||
resolve(makeMapStats(fixChromeStats_(response)));
|
||||
}, reject]);
|
||||
}).then(onSucc, onErr);
|
||||
};
|
||||
}
|
||||
function shimSenderReceiverGetStats(window) {
|
||||
if (!(_typeof(window) === 'object' && window.RTCPeerConnection && window.RTCRtpSender && window.RTCRtpReceiver)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// shim sender stats.
|
||||
if (!('getStats' in window.RTCRtpSender.prototype)) {
|
||||
var origGetSenders = window.RTCPeerConnection.prototype.getSenders;
|
||||
if (origGetSenders) {
|
||||
window.RTCPeerConnection.prototype.getSenders = function getSenders() {
|
||||
var _this6 = this;
|
||||
var senders = origGetSenders.apply(this, []);
|
||||
senders.forEach(function (sender) {
|
||||
return sender._pc = _this6;
|
||||
});
|
||||
return senders;
|
||||
};
|
||||
}
|
||||
var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
|
||||
if (origAddTrack) {
|
||||
window.RTCPeerConnection.prototype.addTrack = function addTrack() {
|
||||
var sender = origAddTrack.apply(this, arguments);
|
||||
sender._pc = this;
|
||||
return sender;
|
||||
};
|
||||
}
|
||||
window.RTCRtpSender.prototype.getStats = function getStats() {
|
||||
var sender = this;
|
||||
return this._pc.getStats().then(function (result) {
|
||||
return (
|
||||
/* Note: this will include stats of all senders that
|
||||
* send a track with the same id as sender.track as
|
||||
* it is not possible to identify the RTCRtpSender.
|
||||
*/
|
||||
utils.filterStats(result, sender.track, true)
|
||||
);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// shim receiver stats.
|
||||
if (!('getStats' in window.RTCRtpReceiver.prototype)) {
|
||||
var origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;
|
||||
if (origGetReceivers) {
|
||||
window.RTCPeerConnection.prototype.getReceivers = function getReceivers() {
|
||||
var _this7 = this;
|
||||
var receivers = origGetReceivers.apply(this, []);
|
||||
receivers.forEach(function (receiver) {
|
||||
return receiver._pc = _this7;
|
||||
});
|
||||
return receivers;
|
||||
};
|
||||
}
|
||||
utils.wrapPeerConnectionEvent(window, 'track', function (e) {
|
||||
e.receiver._pc = e.srcElement;
|
||||
return e;
|
||||
});
|
||||
window.RTCRtpReceiver.prototype.getStats = function getStats() {
|
||||
var receiver = this;
|
||||
return this._pc.getStats().then(function (result) {
|
||||
return utils.filterStats(result, receiver.track, false);
|
||||
});
|
||||
};
|
||||
}
|
||||
if (!('getStats' in window.RTCRtpSender.prototype && 'getStats' in window.RTCRtpReceiver.prototype)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// shim RTCPeerConnection.getStats(track).
|
||||
var origGetStats = window.RTCPeerConnection.prototype.getStats;
|
||||
window.RTCPeerConnection.prototype.getStats = function getStats() {
|
||||
if (arguments.length > 0 && arguments[0] instanceof window.MediaStreamTrack) {
|
||||
var track = arguments[0];
|
||||
var sender;
|
||||
var receiver;
|
||||
var err;
|
||||
this.getSenders().forEach(function (s) {
|
||||
if (s.track === track) {
|
||||
if (sender) {
|
||||
err = true;
|
||||
} else {
|
||||
sender = s;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.getReceivers().forEach(function (r) {
|
||||
if (r.track === track) {
|
||||
if (receiver) {
|
||||
err = true;
|
||||
} else {
|
||||
receiver = r;
|
||||
}
|
||||
}
|
||||
return r.track === track;
|
||||
});
|
||||
if (err || sender && receiver) {
|
||||
return Promise.reject(new DOMException('There are more than one sender or receiver for the track.', 'InvalidAccessError'));
|
||||
} else if (sender) {
|
||||
return sender.getStats();
|
||||
} else if (receiver) {
|
||||
return receiver.getStats();
|
||||
}
|
||||
return Promise.reject(new DOMException('There is no sender or receiver for the track.', 'InvalidAccessError'));
|
||||
}
|
||||
return origGetStats.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
function shimAddTrackRemoveTrackWithNative(window) {
|
||||
// shim addTrack/removeTrack with native variants in order to make
|
||||
// the interactions with legacy getLocalStreams behave as in other browsers.
|
||||
// Keeps a mapping stream.id => [stream, rtpsenders...]
|
||||
window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() {
|
||||
var _this8 = this;
|
||||
this._shimmedLocalStreams = this._shimmedLocalStreams || {};
|
||||
return Object.keys(this._shimmedLocalStreams).map(function (streamId) {
|
||||
return _this8._shimmedLocalStreams[streamId][0];
|
||||
});
|
||||
};
|
||||
var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
|
||||
window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) {
|
||||
if (!stream) {
|
||||
return origAddTrack.apply(this, arguments);
|
||||
}
|
||||
this._shimmedLocalStreams = this._shimmedLocalStreams || {};
|
||||
var sender = origAddTrack.apply(this, arguments);
|
||||
if (!this._shimmedLocalStreams[stream.id]) {
|
||||
this._shimmedLocalStreams[stream.id] = [stream, sender];
|
||||
} else if (this._shimmedLocalStreams[stream.id].indexOf(sender) === -1) {
|
||||
this._shimmedLocalStreams[stream.id].push(sender);
|
||||
}
|
||||
return sender;
|
||||
};
|
||||
var origAddStream = window.RTCPeerConnection.prototype.addStream;
|
||||
window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
|
||||
var _this9 = this;
|
||||
this._shimmedLocalStreams = this._shimmedLocalStreams || {};
|
||||
stream.getTracks().forEach(function (track) {
|
||||
var alreadyExists = _this9.getSenders().find(function (s) {
|
||||
return s.track === track;
|
||||
});
|
||||
if (alreadyExists) {
|
||||
throw new DOMException('Track already exists.', 'InvalidAccessError');
|
||||
}
|
||||
});
|
||||
var existingSenders = this.getSenders();
|
||||
origAddStream.apply(this, arguments);
|
||||
var newSenders = this.getSenders().filter(function (newSender) {
|
||||
return existingSenders.indexOf(newSender) === -1;
|
||||
});
|
||||
this._shimmedLocalStreams[stream.id] = [stream].concat(newSenders);
|
||||
};
|
||||
var origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
|
||||
window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
|
||||
this._shimmedLocalStreams = this._shimmedLocalStreams || {};
|
||||
delete this._shimmedLocalStreams[stream.id];
|
||||
return origRemoveStream.apply(this, arguments);
|
||||
};
|
||||
var origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;
|
||||
window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) {
|
||||
var _this10 = this;
|
||||
this._shimmedLocalStreams = this._shimmedLocalStreams || {};
|
||||
if (sender) {
|
||||
Object.keys(this._shimmedLocalStreams).forEach(function (streamId) {
|
||||
var idx = _this10._shimmedLocalStreams[streamId].indexOf(sender);
|
||||
if (idx !== -1) {
|
||||
_this10._shimmedLocalStreams[streamId].splice(idx, 1);
|
||||
}
|
||||
if (_this10._shimmedLocalStreams[streamId].length === 1) {
|
||||
delete _this10._shimmedLocalStreams[streamId];
|
||||
}
|
||||
});
|
||||
}
|
||||
return origRemoveTrack.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
function shimAddTrackRemoveTrack(window, browserDetails) {
|
||||
if (!window.RTCPeerConnection) {
|
||||
return;
|
||||
}
|
||||
// shim addTrack and removeTrack.
|
||||
if (window.RTCPeerConnection.prototype.addTrack && browserDetails.version >= 65) {
|
||||
return shimAddTrackRemoveTrackWithNative(window);
|
||||
}
|
||||
|
||||
// also shim pc.getLocalStreams when addTrack is shimmed
|
||||
// to return the original streams.
|
||||
var origGetLocalStreams = window.RTCPeerConnection.prototype.getLocalStreams;
|
||||
window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() {
|
||||
var _this11 = this;
|
||||
var nativeStreams = origGetLocalStreams.apply(this);
|
||||
this._reverseStreams = this._reverseStreams || {};
|
||||
return nativeStreams.map(function (stream) {
|
||||
return _this11._reverseStreams[stream.id];
|
||||
});
|
||||
};
|
||||
var origAddStream = window.RTCPeerConnection.prototype.addStream;
|
||||
window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
|
||||
var _this12 = this;
|
||||
this._streams = this._streams || {};
|
||||
this._reverseStreams = this._reverseStreams || {};
|
||||
stream.getTracks().forEach(function (track) {
|
||||
var alreadyExists = _this12.getSenders().find(function (s) {
|
||||
return s.track === track;
|
||||
});
|
||||
if (alreadyExists) {
|
||||
throw new DOMException('Track already exists.', 'InvalidAccessError');
|
||||
}
|
||||
});
|
||||
// Add identity mapping for consistency with addTrack.
|
||||
// Unless this is being used with a stream from addTrack.
|
||||
if (!this._reverseStreams[stream.id]) {
|
||||
var newStream = new window.MediaStream(stream.getTracks());
|
||||
this._streams[stream.id] = newStream;
|
||||
this._reverseStreams[newStream.id] = stream;
|
||||
stream = newStream;
|
||||
}
|
||||
origAddStream.apply(this, [stream]);
|
||||
};
|
||||
var origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
|
||||
window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
|
||||
this._streams = this._streams || {};
|
||||
this._reverseStreams = this._reverseStreams || {};
|
||||
origRemoveStream.apply(this, [this._streams[stream.id] || stream]);
|
||||
delete this._reverseStreams[this._streams[stream.id] ? this._streams[stream.id].id : stream.id];
|
||||
delete this._streams[stream.id];
|
||||
};
|
||||
window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) {
|
||||
var _this13 = this;
|
||||
if (this.signalingState === 'closed') {
|
||||
throw new DOMException('The RTCPeerConnection\'s signalingState is \'closed\'.', 'InvalidStateError');
|
||||
}
|
||||
var streams = [].slice.call(arguments, 1);
|
||||
if (streams.length !== 1 || !streams[0].getTracks().find(function (t) {
|
||||
return t === track;
|
||||
})) {
|
||||
// this is not fully correct but all we can manage without
|
||||
// [[associated MediaStreams]] internal slot.
|
||||
throw new DOMException('The adapter.js addTrack polyfill only supports a single ' + ' stream which is associated with the specified track.', 'NotSupportedError');
|
||||
}
|
||||
var alreadyExists = this.getSenders().find(function (s) {
|
||||
return s.track === track;
|
||||
});
|
||||
if (alreadyExists) {
|
||||
throw new DOMException('Track already exists.', 'InvalidAccessError');
|
||||
}
|
||||
this._streams = this._streams || {};
|
||||
this._reverseStreams = this._reverseStreams || {};
|
||||
var oldStream = this._streams[stream.id];
|
||||
if (oldStream) {
|
||||
// this is using odd Chrome behaviour, use with caution:
|
||||
// https://bugs.chromium.org/p/webrtc/issues/detail?id=7815
|
||||
// Note: we rely on the high-level addTrack/dtmf shim to
|
||||
// create the sender with a dtmf sender.
|
||||
oldStream.addTrack(track);
|
||||
|
||||
// Trigger ONN async.
|
||||
Promise.resolve().then(function () {
|
||||
_this13.dispatchEvent(new Event('negotiationneeded'));
|
||||
});
|
||||
} else {
|
||||
var newStream = new window.MediaStream([track]);
|
||||
this._streams[stream.id] = newStream;
|
||||
this._reverseStreams[newStream.id] = stream;
|
||||
this.addStream(newStream);
|
||||
}
|
||||
return this.getSenders().find(function (s) {
|
||||
return s.track === track;
|
||||
});
|
||||
};
|
||||
|
||||
// replace the internal stream id with the external one and
|
||||
// vice versa.
|
||||
function replaceInternalStreamId(pc, description) {
|
||||
var sdp = description.sdp;
|
||||
Object.keys(pc._reverseStreams || []).forEach(function (internalId) {
|
||||
var externalStream = pc._reverseStreams[internalId];
|
||||
var internalStream = pc._streams[externalStream.id];
|
||||
sdp = sdp.replace(new RegExp(internalStream.id, 'g'), externalStream.id);
|
||||
});
|
||||
return new RTCSessionDescription({
|
||||
type: description.type,
|
||||
sdp: sdp
|
||||
});
|
||||
}
|
||||
function replaceExternalStreamId(pc, description) {
|
||||
var sdp = description.sdp;
|
||||
Object.keys(pc._reverseStreams || []).forEach(function (internalId) {
|
||||
var externalStream = pc._reverseStreams[internalId];
|
||||
var internalStream = pc._streams[externalStream.id];
|
||||
sdp = sdp.replace(new RegExp(externalStream.id, 'g'), internalStream.id);
|
||||
});
|
||||
return new RTCSessionDescription({
|
||||
type: description.type,
|
||||
sdp: sdp
|
||||
});
|
||||
}
|
||||
['createOffer', 'createAnswer'].forEach(function (method) {
|
||||
var nativeMethod = window.RTCPeerConnection.prototype[method];
|
||||
var methodObj = _defineProperty({}, method, function () {
|
||||
var _this14 = this;
|
||||
var args = arguments;
|
||||
var isLegacyCall = arguments.length && typeof arguments[0] === 'function';
|
||||
if (isLegacyCall) {
|
||||
return nativeMethod.apply(this, [function (description) {
|
||||
var desc = replaceInternalStreamId(_this14, description);
|
||||
args[0].apply(null, [desc]);
|
||||
}, function (err) {
|
||||
if (args[1]) {
|
||||
args[1].apply(null, err);
|
||||
}
|
||||
}, arguments[2]]);
|
||||
}
|
||||
return nativeMethod.apply(this, arguments).then(function (description) {
|
||||
return replaceInternalStreamId(_this14, description);
|
||||
});
|
||||
});
|
||||
window.RTCPeerConnection.prototype[method] = methodObj[method];
|
||||
});
|
||||
var origSetLocalDescription = window.RTCPeerConnection.prototype.setLocalDescription;
|
||||
window.RTCPeerConnection.prototype.setLocalDescription = function setLocalDescription() {
|
||||
if (!arguments.length || !arguments[0].type) {
|
||||
return origSetLocalDescription.apply(this, arguments);
|
||||
}
|
||||
arguments[0] = replaceExternalStreamId(this, arguments[0]);
|
||||
return origSetLocalDescription.apply(this, arguments);
|
||||
};
|
||||
|
||||
// TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier
|
||||
|
||||
var origLocalDescription = Object.getOwnPropertyDescriptor(window.RTCPeerConnection.prototype, 'localDescription');
|
||||
Object.defineProperty(window.RTCPeerConnection.prototype, 'localDescription', {
|
||||
get: function get() {
|
||||
var description = origLocalDescription.get.apply(this);
|
||||
if (description.type === '') {
|
||||
return description;
|
||||
}
|
||||
return replaceInternalStreamId(this, description);
|
||||
}
|
||||
});
|
||||
window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) {
|
||||
var _this15 = this;
|
||||
if (this.signalingState === 'closed') {
|
||||
throw new DOMException('The RTCPeerConnection\'s signalingState is \'closed\'.', 'InvalidStateError');
|
||||
}
|
||||
// We can not yet check for sender instanceof RTCRtpSender
|
||||
// since we shim RTPSender. So we check if sender._pc is set.
|
||||
if (!sender._pc) {
|
||||
throw new DOMException('Argument 1 of RTCPeerConnection.removeTrack ' + 'does not implement interface RTCRtpSender.', 'TypeError');
|
||||
}
|
||||
var isLocal = sender._pc === this;
|
||||
if (!isLocal) {
|
||||
throw new DOMException('Sender was not created by this connection.', 'InvalidAccessError');
|
||||
}
|
||||
|
||||
// Search for the native stream the senders track belongs to.
|
||||
this._streams = this._streams || {};
|
||||
var stream;
|
||||
Object.keys(this._streams).forEach(function (streamid) {
|
||||
var hasTrack = _this15._streams[streamid].getTracks().find(function (track) {
|
||||
return sender.track === track;
|
||||
});
|
||||
if (hasTrack) {
|
||||
stream = _this15._streams[streamid];
|
||||
}
|
||||
});
|
||||
if (stream) {
|
||||
if (stream.getTracks().length === 1) {
|
||||
// if this is the last track of the stream, remove the stream. This
|
||||
// takes care of any shimmed _senders.
|
||||
this.removeStream(this._reverseStreams[stream.id]);
|
||||
} else {
|
||||
// relying on the same odd chrome behaviour as above.
|
||||
stream.removeTrack(sender.track);
|
||||
}
|
||||
this.dispatchEvent(new Event('negotiationneeded'));
|
||||
}
|
||||
};
|
||||
}
|
||||
function shimPeerConnection(window, browserDetails) {
|
||||
if (!window.RTCPeerConnection && window.webkitRTCPeerConnection) {
|
||||
// very basic support for old versions.
|
||||
window.RTCPeerConnection = window.webkitRTCPeerConnection;
|
||||
}
|
||||
if (!window.RTCPeerConnection) {
|
||||
return;
|
||||
}
|
||||
|
||||
// shim implicit creation of RTCSessionDescription/RTCIceCandidate
|
||||
if (browserDetails.version < 53) {
|
||||
['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'].forEach(function (method) {
|
||||
var nativeMethod = window.RTCPeerConnection.prototype[method];
|
||||
var methodObj = _defineProperty({}, method, function () {
|
||||
arguments[0] = new (method === 'addIceCandidate' ? window.RTCIceCandidate : window.RTCSessionDescription)(arguments[0]);
|
||||
return nativeMethod.apply(this, arguments);
|
||||
});
|
||||
window.RTCPeerConnection.prototype[method] = methodObj[method];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to fix ONN in plan-b mode.
|
||||
function fixNegotiationNeeded(window, browserDetails) {
|
||||
utils.wrapPeerConnectionEvent(window, 'negotiationneeded', function (e) {
|
||||
var pc = e.target;
|
||||
if (browserDetails.version < 72 || pc.getConfiguration && pc.getConfiguration().sdpSemantics === 'plan-b') {
|
||||
if (pc.signalingState !== 'stable') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
});
|
||||
}
|
49
node_modules/webrtc-adapter/dist/chrome/getdisplaymedia.js
generated
vendored
Normal file
49
node_modules/webrtc-adapter/dist/chrome/getdisplaymedia.js
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.shimGetDisplayMedia = shimGetDisplayMedia;
|
||||
function shimGetDisplayMedia(window, getSourceId) {
|
||||
if (window.navigator.mediaDevices && 'getDisplayMedia' in window.navigator.mediaDevices) {
|
||||
return;
|
||||
}
|
||||
if (!window.navigator.mediaDevices) {
|
||||
return;
|
||||
}
|
||||
// getSourceId is a function that returns a promise resolving with
|
||||
// the sourceId of the screen/window/tab to be shared.
|
||||
if (typeof getSourceId !== 'function') {
|
||||
console.error('shimGetDisplayMedia: getSourceId argument is not ' + 'a function');
|
||||
return;
|
||||
}
|
||||
window.navigator.mediaDevices.getDisplayMedia = function getDisplayMedia(constraints) {
|
||||
return getSourceId(constraints).then(function (sourceId) {
|
||||
var widthSpecified = constraints.video && constraints.video.width;
|
||||
var heightSpecified = constraints.video && constraints.video.height;
|
||||
var frameRateSpecified = constraints.video && constraints.video.frameRate;
|
||||
constraints.video = {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'desktop',
|
||||
chromeMediaSourceId: sourceId,
|
||||
maxFrameRate: frameRateSpecified || 3
|
||||
}
|
||||
};
|
||||
if (widthSpecified) {
|
||||
constraints.video.mandatory.maxWidth = widthSpecified;
|
||||
}
|
||||
if (heightSpecified) {
|
||||
constraints.video.mandatory.maxHeight = heightSpecified;
|
||||
}
|
||||
return window.navigator.mediaDevices.getUserMedia(constraints);
|
||||
});
|
||||
};
|
||||
}
|
199
node_modules/webrtc-adapter/dist/chrome/getusermedia.js
generated
vendored
Normal file
199
node_modules/webrtc-adapter/dist/chrome/getusermedia.js
generated
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.shimGetUserMedia = shimGetUserMedia;
|
||||
var utils = _interopRequireWildcard(require("../utils.js"));
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
||||
var logging = utils.log;
|
||||
function shimGetUserMedia(window, browserDetails) {
|
||||
var navigator = window && window.navigator;
|
||||
if (!navigator.mediaDevices) {
|
||||
return;
|
||||
}
|
||||
var constraintsToChrome_ = function constraintsToChrome_(c) {
|
||||
if (_typeof(c) !== 'object' || c.mandatory || c.optional) {
|
||||
return c;
|
||||
}
|
||||
var cc = {};
|
||||
Object.keys(c).forEach(function (key) {
|
||||
if (key === 'require' || key === 'advanced' || key === 'mediaSource') {
|
||||
return;
|
||||
}
|
||||
var r = _typeof(c[key]) === 'object' ? c[key] : {
|
||||
ideal: c[key]
|
||||
};
|
||||
if (r.exact !== undefined && typeof r.exact === 'number') {
|
||||
r.min = r.max = r.exact;
|
||||
}
|
||||
var oldname_ = function oldname_(prefix, name) {
|
||||
if (prefix) {
|
||||
return prefix + name.charAt(0).toUpperCase() + name.slice(1);
|
||||
}
|
||||
return name === 'deviceId' ? 'sourceId' : name;
|
||||
};
|
||||
if (r.ideal !== undefined) {
|
||||
cc.optional = cc.optional || [];
|
||||
var oc = {};
|
||||
if (typeof r.ideal === 'number') {
|
||||
oc[oldname_('min', key)] = r.ideal;
|
||||
cc.optional.push(oc);
|
||||
oc = {};
|
||||
oc[oldname_('max', key)] = r.ideal;
|
||||
cc.optional.push(oc);
|
||||
} else {
|
||||
oc[oldname_('', key)] = r.ideal;
|
||||
cc.optional.push(oc);
|
||||
}
|
||||
}
|
||||
if (r.exact !== undefined && typeof r.exact !== 'number') {
|
||||
cc.mandatory = cc.mandatory || {};
|
||||
cc.mandatory[oldname_('', key)] = r.exact;
|
||||
} else {
|
||||
['min', 'max'].forEach(function (mix) {
|
||||
if (r[mix] !== undefined) {
|
||||
cc.mandatory = cc.mandatory || {};
|
||||
cc.mandatory[oldname_(mix, key)] = r[mix];
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
if (c.advanced) {
|
||||
cc.optional = (cc.optional || []).concat(c.advanced);
|
||||
}
|
||||
return cc;
|
||||
};
|
||||
var shimConstraints_ = function shimConstraints_(constraints, func) {
|
||||
if (browserDetails.version >= 61) {
|
||||
return func(constraints);
|
||||
}
|
||||
constraints = JSON.parse(JSON.stringify(constraints));
|
||||
if (constraints && _typeof(constraints.audio) === 'object') {
|
||||
var remap = function remap(obj, a, b) {
|
||||
if (a in obj && !(b in obj)) {
|
||||
obj[b] = obj[a];
|
||||
delete obj[a];
|
||||
}
|
||||
};
|
||||
constraints = JSON.parse(JSON.stringify(constraints));
|
||||
remap(constraints.audio, 'autoGainControl', 'googAutoGainControl');
|
||||
remap(constraints.audio, 'noiseSuppression', 'googNoiseSuppression');
|
||||
constraints.audio = constraintsToChrome_(constraints.audio);
|
||||
}
|
||||
if (constraints && _typeof(constraints.video) === 'object') {
|
||||
// Shim facingMode for mobile & surface pro.
|
||||
var face = constraints.video.facingMode;
|
||||
face = face && (_typeof(face) === 'object' ? face : {
|
||||
ideal: face
|
||||
});
|
||||
var getSupportedFacingModeLies = browserDetails.version < 66;
|
||||
if (face && (face.exact === 'user' || face.exact === 'environment' || face.ideal === 'user' || face.ideal === 'environment') && !(navigator.mediaDevices.getSupportedConstraints && navigator.mediaDevices.getSupportedConstraints().facingMode && !getSupportedFacingModeLies)) {
|
||||
delete constraints.video.facingMode;
|
||||
var matches;
|
||||
if (face.exact === 'environment' || face.ideal === 'environment') {
|
||||
matches = ['back', 'rear'];
|
||||
} else if (face.exact === 'user' || face.ideal === 'user') {
|
||||
matches = ['front'];
|
||||
}
|
||||
if (matches) {
|
||||
// Look for matches in label, or use last cam for back (typical).
|
||||
return navigator.mediaDevices.enumerateDevices().then(function (devices) {
|
||||
devices = devices.filter(function (d) {
|
||||
return d.kind === 'videoinput';
|
||||
});
|
||||
var dev = devices.find(function (d) {
|
||||
return matches.some(function (match) {
|
||||
return d.label.toLowerCase().includes(match);
|
||||
});
|
||||
});
|
||||
if (!dev && devices.length && matches.includes('back')) {
|
||||
dev = devices[devices.length - 1]; // more likely the back cam
|
||||
}
|
||||
|
||||
if (dev) {
|
||||
constraints.video.deviceId = face.exact ? {
|
||||
exact: dev.deviceId
|
||||
} : {
|
||||
ideal: dev.deviceId
|
||||
};
|
||||
}
|
||||
constraints.video = constraintsToChrome_(constraints.video);
|
||||
logging('chrome: ' + JSON.stringify(constraints));
|
||||
return func(constraints);
|
||||
});
|
||||
}
|
||||
}
|
||||
constraints.video = constraintsToChrome_(constraints.video);
|
||||
}
|
||||
logging('chrome: ' + JSON.stringify(constraints));
|
||||
return func(constraints);
|
||||
};
|
||||
var shimError_ = function shimError_(e) {
|
||||
if (browserDetails.version >= 64) {
|
||||
return e;
|
||||
}
|
||||
return {
|
||||
name: {
|
||||
PermissionDeniedError: 'NotAllowedError',
|
||||
PermissionDismissedError: 'NotAllowedError',
|
||||
InvalidStateError: 'NotAllowedError',
|
||||
DevicesNotFoundError: 'NotFoundError',
|
||||
ConstraintNotSatisfiedError: 'OverconstrainedError',
|
||||
TrackStartError: 'NotReadableError',
|
||||
MediaDeviceFailedDueToShutdown: 'NotAllowedError',
|
||||
MediaDeviceKillSwitchOn: 'NotAllowedError',
|
||||
TabCaptureError: 'AbortError',
|
||||
ScreenCaptureError: 'AbortError',
|
||||
DeviceCaptureError: 'AbortError'
|
||||
}[e.name] || e.name,
|
||||
message: e.message,
|
||||
constraint: e.constraint || e.constraintName,
|
||||
toString: function toString() {
|
||||
return this.name + (this.message && ': ') + this.message;
|
||||
}
|
||||
};
|
||||
};
|
||||
var getUserMedia_ = function getUserMedia_(constraints, onSuccess, onError) {
|
||||
shimConstraints_(constraints, function (c) {
|
||||
navigator.webkitGetUserMedia(c, onSuccess, function (e) {
|
||||
if (onError) {
|
||||
onError(shimError_(e));
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
navigator.getUserMedia = getUserMedia_.bind(navigator);
|
||||
|
||||
// Even though Chrome 45 has navigator.mediaDevices and a getUserMedia
|
||||
// function which returns a Promise, it does not accept spec-style
|
||||
// constraints.
|
||||
if (navigator.mediaDevices.getUserMedia) {
|
||||
var origGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
|
||||
navigator.mediaDevices.getUserMedia = function (cs) {
|
||||
return shimConstraints_(cs, function (c) {
|
||||
return origGetUserMedia(c).then(function (stream) {
|
||||
if (c.audio && !stream.getAudioTracks().length || c.video && !stream.getVideoTracks().length) {
|
||||
stream.getTracks().forEach(function (track) {
|
||||
track.stop();
|
||||
});
|
||||
throw new DOMException('', 'NotFoundError');
|
||||
}
|
||||
return stream;
|
||||
}, function (e) {
|
||||
return Promise.reject(shimError_(e));
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
40
node_modules/webrtc-adapter/dist/chrome/selectaudiooutput.js
generated
vendored
Normal file
40
node_modules/webrtc-adapter/dist/chrome/selectaudiooutput.js
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2022 The adapter.js project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.shimSelectAudioOutput = shimSelectAudioOutput;
|
||||
function shimSelectAudioOutput(window) {
|
||||
// Polyfillying only makes sense when setSinkId is available
|
||||
// and the function is not already there.
|
||||
if (!('HTMLMediaElement' in window)) {
|
||||
return;
|
||||
}
|
||||
if (!('setSinkId' in window.HTMLMediaElement.prototype)) {
|
||||
return;
|
||||
}
|
||||
if (!(window.navigator && window.navigator.mediaDevices)) {
|
||||
return;
|
||||
}
|
||||
if (!window.navigator.mediaDevices.enumerateDevices) {
|
||||
return;
|
||||
}
|
||||
if (window.navigator.mediaDevices.selectAudioOutput) {
|
||||
return;
|
||||
}
|
||||
window.navigator.mediaDevices.selectAudioOutput = function () {
|
||||
return window.navigator.mediaDevices.enumerateDevices().then(function (devices) {
|
||||
return devices.filter(function (d) {
|
||||
return d.kind === 'audiooutput';
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
436
node_modules/webrtc-adapter/dist/common_shim.js
generated
vendored
Normal file
436
node_modules/webrtc-adapter/dist/common_shim.js
generated
vendored
Normal file
@ -0,0 +1,436 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.removeExtmapAllowMixed = removeExtmapAllowMixed;
|
||||
exports.shimAddIceCandidateNullOrEmpty = shimAddIceCandidateNullOrEmpty;
|
||||
exports.shimConnectionState = shimConnectionState;
|
||||
exports.shimMaxMessageSize = shimMaxMessageSize;
|
||||
exports.shimParameterlessSetLocalDescription = shimParameterlessSetLocalDescription;
|
||||
exports.shimRTCIceCandidate = shimRTCIceCandidate;
|
||||
exports.shimRTCIceCandidateRelayProtocol = shimRTCIceCandidateRelayProtocol;
|
||||
exports.shimSendThrowTypeError = shimSendThrowTypeError;
|
||||
var _sdp = _interopRequireDefault(require("sdp"));
|
||||
var utils = _interopRequireWildcard(require("./utils"));
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
||||
function shimRTCIceCandidate(window) {
|
||||
// foundation is arbitrarily chosen as an indicator for full support for
|
||||
// https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface
|
||||
if (!window.RTCIceCandidate || window.RTCIceCandidate && 'foundation' in window.RTCIceCandidate.prototype) {
|
||||
return;
|
||||
}
|
||||
var NativeRTCIceCandidate = window.RTCIceCandidate;
|
||||
window.RTCIceCandidate = function RTCIceCandidate(args) {
|
||||
// Remove the a= which shouldn't be part of the candidate string.
|
||||
if (_typeof(args) === 'object' && args.candidate && args.candidate.indexOf('a=') === 0) {
|
||||
args = JSON.parse(JSON.stringify(args));
|
||||
args.candidate = args.candidate.substring(2);
|
||||
}
|
||||
if (args.candidate && args.candidate.length) {
|
||||
// Augment the native candidate with the parsed fields.
|
||||
var nativeCandidate = new NativeRTCIceCandidate(args);
|
||||
var parsedCandidate = _sdp["default"].parseCandidate(args.candidate);
|
||||
for (var key in parsedCandidate) {
|
||||
if (!(key in nativeCandidate)) {
|
||||
Object.defineProperty(nativeCandidate, key, {
|
||||
value: parsedCandidate[key]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Override serializer to not serialize the extra attributes.
|
||||
nativeCandidate.toJSON = function toJSON() {
|
||||
return {
|
||||
candidate: nativeCandidate.candidate,
|
||||
sdpMid: nativeCandidate.sdpMid,
|
||||
sdpMLineIndex: nativeCandidate.sdpMLineIndex,
|
||||
usernameFragment: nativeCandidate.usernameFragment
|
||||
};
|
||||
};
|
||||
return nativeCandidate;
|
||||
}
|
||||
return new NativeRTCIceCandidate(args);
|
||||
};
|
||||
window.RTCIceCandidate.prototype = NativeRTCIceCandidate.prototype;
|
||||
|
||||
// Hook up the augmented candidate in onicecandidate and
|
||||
// addEventListener('icecandidate', ...)
|
||||
utils.wrapPeerConnectionEvent(window, 'icecandidate', function (e) {
|
||||
if (e.candidate) {
|
||||
Object.defineProperty(e, 'candidate', {
|
||||
value: new window.RTCIceCandidate(e.candidate),
|
||||
writable: 'false'
|
||||
});
|
||||
}
|
||||
return e;
|
||||
});
|
||||
}
|
||||
function shimRTCIceCandidateRelayProtocol(window) {
|
||||
if (!window.RTCIceCandidate || window.RTCIceCandidate && 'relayProtocol' in window.RTCIceCandidate.prototype) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Hook up the augmented candidate in onicecandidate and
|
||||
// addEventListener('icecandidate', ...)
|
||||
utils.wrapPeerConnectionEvent(window, 'icecandidate', function (e) {
|
||||
if (e.candidate) {
|
||||
var parsedCandidate = _sdp["default"].parseCandidate(e.candidate.candidate);
|
||||
if (parsedCandidate.type === 'relay') {
|
||||
// This is a libwebrtc-specific mapping of local type preference
|
||||
// to relayProtocol.
|
||||
e.candidate.relayProtocol = {
|
||||
0: 'tls',
|
||||
1: 'tcp',
|
||||
2: 'udp'
|
||||
}[parsedCandidate.priority >> 24];
|
||||
}
|
||||
}
|
||||
return e;
|
||||
});
|
||||
}
|
||||
function shimMaxMessageSize(window, browserDetails) {
|
||||
if (!window.RTCPeerConnection) {
|
||||
return;
|
||||
}
|
||||
if (!('sctp' in window.RTCPeerConnection.prototype)) {
|
||||
Object.defineProperty(window.RTCPeerConnection.prototype, 'sctp', {
|
||||
get: function get() {
|
||||
return typeof this._sctp === 'undefined' ? null : this._sctp;
|
||||
}
|
||||
});
|
||||
}
|
||||
var sctpInDescription = function sctpInDescription(description) {
|
||||
if (!description || !description.sdp) {
|
||||
return false;
|
||||
}
|
||||
var sections = _sdp["default"].splitSections(description.sdp);
|
||||
sections.shift();
|
||||
return sections.some(function (mediaSection) {
|
||||
var mLine = _sdp["default"].parseMLine(mediaSection);
|
||||
return mLine && mLine.kind === 'application' && mLine.protocol.indexOf('SCTP') !== -1;
|
||||
});
|
||||
};
|
||||
var getRemoteFirefoxVersion = function getRemoteFirefoxVersion(description) {
|
||||
// TODO: Is there a better solution for detecting Firefox?
|
||||
var match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\d+)/);
|
||||
if (match === null || match.length < 2) {
|
||||
return -1;
|
||||
}
|
||||
var version = parseInt(match[1], 10);
|
||||
// Test for NaN (yes, this is ugly)
|
||||
return version !== version ? -1 : version;
|
||||
};
|
||||
var getCanSendMaxMessageSize = function getCanSendMaxMessageSize(remoteIsFirefox) {
|
||||
// Every implementation we know can send at least 64 KiB.
|
||||
// Note: Although Chrome is technically able to send up to 256 KiB, the
|
||||
// data does not reach the other peer reliably.
|
||||
// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419
|
||||
var canSendMaxMessageSize = 65536;
|
||||
if (browserDetails.browser === 'firefox') {
|
||||
if (browserDetails.version < 57) {
|
||||
if (remoteIsFirefox === -1) {
|
||||
// FF < 57 will send in 16 KiB chunks using the deprecated PPID
|
||||
// fragmentation.
|
||||
canSendMaxMessageSize = 16384;
|
||||
} else {
|
||||
// However, other FF (and RAWRTC) can reassemble PPID-fragmented
|
||||
// messages. Thus, supporting ~2 GiB when sending.
|
||||
canSendMaxMessageSize = 2147483637;
|
||||
}
|
||||
} else if (browserDetails.version < 60) {
|
||||
// Currently, all FF >= 57 will reset the remote maximum message size
|
||||
// to the default value when a data channel is created at a later
|
||||
// stage. :(
|
||||
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831
|
||||
canSendMaxMessageSize = browserDetails.version === 57 ? 65535 : 65536;
|
||||
} else {
|
||||
// FF >= 60 supports sending ~2 GiB
|
||||
canSendMaxMessageSize = 2147483637;
|
||||
}
|
||||
}
|
||||
return canSendMaxMessageSize;
|
||||
};
|
||||
var getMaxMessageSize = function getMaxMessageSize(description, remoteIsFirefox) {
|
||||
// Note: 65536 bytes is the default value from the SDP spec. Also,
|
||||
// every implementation we know supports receiving 65536 bytes.
|
||||
var maxMessageSize = 65536;
|
||||
|
||||
// FF 57 has a slightly incorrect default remote max message size, so
|
||||
// we need to adjust it here to avoid a failure when sending.
|
||||
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697
|
||||
if (browserDetails.browser === 'firefox' && browserDetails.version === 57) {
|
||||
maxMessageSize = 65535;
|
||||
}
|
||||
var match = _sdp["default"].matchPrefix(description.sdp, 'a=max-message-size:');
|
||||
if (match.length > 0) {
|
||||
maxMessageSize = parseInt(match[0].substring(19), 10);
|
||||
} else if (browserDetails.browser === 'firefox' && remoteIsFirefox !== -1) {
|
||||
// If the maximum message size is not present in the remote SDP and
|
||||
// both local and remote are Firefox, the remote peer can receive
|
||||
// ~2 GiB.
|
||||
maxMessageSize = 2147483637;
|
||||
}
|
||||
return maxMessageSize;
|
||||
};
|
||||
var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription;
|
||||
window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() {
|
||||
this._sctp = null;
|
||||
// Chrome decided to not expose .sctp in plan-b mode.
|
||||
// As usual, adapter.js has to do an 'ugly worakaround'
|
||||
// to cover up the mess.
|
||||
if (browserDetails.browser === 'chrome' && browserDetails.version >= 76) {
|
||||
var _this$getConfiguratio = this.getConfiguration(),
|
||||
sdpSemantics = _this$getConfiguratio.sdpSemantics;
|
||||
if (sdpSemantics === 'plan-b') {
|
||||
Object.defineProperty(this, 'sctp', {
|
||||
get: function get() {
|
||||
return typeof this._sctp === 'undefined' ? null : this._sctp;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
if (sctpInDescription(arguments[0])) {
|
||||
// Check if the remote is FF.
|
||||
var isFirefox = getRemoteFirefoxVersion(arguments[0]);
|
||||
|
||||
// Get the maximum message size the local peer is capable of sending
|
||||
var canSendMMS = getCanSendMaxMessageSize(isFirefox);
|
||||
|
||||
// Get the maximum message size of the remote peer.
|
||||
var remoteMMS = getMaxMessageSize(arguments[0], isFirefox);
|
||||
|
||||
// Determine final maximum message size
|
||||
var maxMessageSize;
|
||||
if (canSendMMS === 0 && remoteMMS === 0) {
|
||||
maxMessageSize = Number.POSITIVE_INFINITY;
|
||||
} else if (canSendMMS === 0 || remoteMMS === 0) {
|
||||
maxMessageSize = Math.max(canSendMMS, remoteMMS);
|
||||
} else {
|
||||
maxMessageSize = Math.min(canSendMMS, remoteMMS);
|
||||
}
|
||||
|
||||
// Create a dummy RTCSctpTransport object and the 'maxMessageSize'
|
||||
// attribute.
|
||||
var sctp = {};
|
||||
Object.defineProperty(sctp, 'maxMessageSize', {
|
||||
get: function get() {
|
||||
return maxMessageSize;
|
||||
}
|
||||
});
|
||||
this._sctp = sctp;
|
||||
}
|
||||
return origSetRemoteDescription.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
function shimSendThrowTypeError(window) {
|
||||
if (!(window.RTCPeerConnection && 'createDataChannel' in window.RTCPeerConnection.prototype)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: Although Firefox >= 57 has a native implementation, the maximum
|
||||
// message size can be reset for all data channels at a later stage.
|
||||
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831
|
||||
|
||||
function wrapDcSend(dc, pc) {
|
||||
var origDataChannelSend = dc.send;
|
||||
dc.send = function send() {
|
||||
var data = arguments[0];
|
||||
var length = data.length || data.size || data.byteLength;
|
||||
if (dc.readyState === 'open' && pc.sctp && length > pc.sctp.maxMessageSize) {
|
||||
throw new TypeError('Message too large (can send a maximum of ' + pc.sctp.maxMessageSize + ' bytes)');
|
||||
}
|
||||
return origDataChannelSend.apply(dc, arguments);
|
||||
};
|
||||
}
|
||||
var origCreateDataChannel = window.RTCPeerConnection.prototype.createDataChannel;
|
||||
window.RTCPeerConnection.prototype.createDataChannel = function createDataChannel() {
|
||||
var dataChannel = origCreateDataChannel.apply(this, arguments);
|
||||
wrapDcSend(dataChannel, this);
|
||||
return dataChannel;
|
||||
};
|
||||
utils.wrapPeerConnectionEvent(window, 'datachannel', function (e) {
|
||||
wrapDcSend(e.channel, e.target);
|
||||
return e;
|
||||
});
|
||||
}
|
||||
|
||||
/* shims RTCConnectionState by pretending it is the same as iceConnectionState.
|
||||
* See https://bugs.chromium.org/p/webrtc/issues/detail?id=6145#c12
|
||||
* for why this is a valid hack in Chrome. In Firefox it is slightly incorrect
|
||||
* since DTLS failures would be hidden. See
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=1265827
|
||||
* for the Firefox tracking bug.
|
||||
*/
|
||||
function shimConnectionState(window) {
|
||||
if (!window.RTCPeerConnection || 'connectionState' in window.RTCPeerConnection.prototype) {
|
||||
return;
|
||||
}
|
||||
var proto = window.RTCPeerConnection.prototype;
|
||||
Object.defineProperty(proto, 'connectionState', {
|
||||
get: function get() {
|
||||
return {
|
||||
completed: 'connected',
|
||||
checking: 'connecting'
|
||||
}[this.iceConnectionState] || this.iceConnectionState;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(proto, 'onconnectionstatechange', {
|
||||
get: function get() {
|
||||
return this._onconnectionstatechange || null;
|
||||
},
|
||||
set: function set(cb) {
|
||||
if (this._onconnectionstatechange) {
|
||||
this.removeEventListener('connectionstatechange', this._onconnectionstatechange);
|
||||
delete this._onconnectionstatechange;
|
||||
}
|
||||
if (cb) {
|
||||
this.addEventListener('connectionstatechange', this._onconnectionstatechange = cb);
|
||||
}
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
['setLocalDescription', 'setRemoteDescription'].forEach(function (method) {
|
||||
var origMethod = proto[method];
|
||||
proto[method] = function () {
|
||||
if (!this._connectionstatechangepoly) {
|
||||
this._connectionstatechangepoly = function (e) {
|
||||
var pc = e.target;
|
||||
if (pc._lastConnectionState !== pc.connectionState) {
|
||||
pc._lastConnectionState = pc.connectionState;
|
||||
var newEvent = new Event('connectionstatechange', e);
|
||||
pc.dispatchEvent(newEvent);
|
||||
}
|
||||
return e;
|
||||
};
|
||||
this.addEventListener('iceconnectionstatechange', this._connectionstatechangepoly);
|
||||
}
|
||||
return origMethod.apply(this, arguments);
|
||||
};
|
||||
});
|
||||
}
|
||||
function removeExtmapAllowMixed(window, browserDetails) {
|
||||
/* remove a=extmap-allow-mixed for webrtc.org < M71 */
|
||||
if (!window.RTCPeerConnection) {
|
||||
return;
|
||||
}
|
||||
if (browserDetails.browser === 'chrome' && browserDetails.version >= 71) {
|
||||
return;
|
||||
}
|
||||
if (browserDetails.browser === 'safari' && browserDetails.version >= 605) {
|
||||
return;
|
||||
}
|
||||
var nativeSRD = window.RTCPeerConnection.prototype.setRemoteDescription;
|
||||
window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription(desc) {
|
||||
if (desc && desc.sdp && desc.sdp.indexOf('\na=extmap-allow-mixed') !== -1) {
|
||||
var sdp = desc.sdp.split('\n').filter(function (line) {
|
||||
return line.trim() !== 'a=extmap-allow-mixed';
|
||||
}).join('\n');
|
||||
// Safari enforces read-only-ness of RTCSessionDescription fields.
|
||||
if (window.RTCSessionDescription && desc instanceof window.RTCSessionDescription) {
|
||||
arguments[0] = new window.RTCSessionDescription({
|
||||
type: desc.type,
|
||||
sdp: sdp
|
||||
});
|
||||
} else {
|
||||
desc.sdp = sdp;
|
||||
}
|
||||
}
|
||||
return nativeSRD.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
function shimAddIceCandidateNullOrEmpty(window, browserDetails) {
|
||||
// Support for addIceCandidate(null or undefined)
|
||||
// as well as addIceCandidate({candidate: "", ...})
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=978582
|
||||
// Note: must be called before other polyfills which change the signature.
|
||||
if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) {
|
||||
return;
|
||||
}
|
||||
var nativeAddIceCandidate = window.RTCPeerConnection.prototype.addIceCandidate;
|
||||
if (!nativeAddIceCandidate || nativeAddIceCandidate.length === 0) {
|
||||
return;
|
||||
}
|
||||
window.RTCPeerConnection.prototype.addIceCandidate = function addIceCandidate() {
|
||||
if (!arguments[0]) {
|
||||
if (arguments[1]) {
|
||||
arguments[1].apply(null);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
// Firefox 68+ emits and processes {candidate: "", ...}, ignore
|
||||
// in older versions.
|
||||
// Native support for ignoring exists for Chrome M77+.
|
||||
// Safari ignores as well, exact version unknown but works in the same
|
||||
// version that also ignores addIceCandidate(null).
|
||||
if ((browserDetails.browser === 'chrome' && browserDetails.version < 78 || browserDetails.browser === 'firefox' && browserDetails.version < 68 || browserDetails.browser === 'safari') && arguments[0] && arguments[0].candidate === '') {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return nativeAddIceCandidate.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
// Note: Make sure to call this ahead of APIs that modify
|
||||
// setLocalDescription.length
|
||||
function shimParameterlessSetLocalDescription(window, browserDetails) {
|
||||
if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) {
|
||||
return;
|
||||
}
|
||||
var nativeSetLocalDescription = window.RTCPeerConnection.prototype.setLocalDescription;
|
||||
if (!nativeSetLocalDescription || nativeSetLocalDescription.length === 0) {
|
||||
return;
|
||||
}
|
||||
window.RTCPeerConnection.prototype.setLocalDescription = function setLocalDescription() {
|
||||
var _this = this;
|
||||
var desc = arguments[0] || {};
|
||||
if (_typeof(desc) !== 'object' || desc.type && desc.sdp) {
|
||||
return nativeSetLocalDescription.apply(this, arguments);
|
||||
}
|
||||
// The remaining steps should technically happen when SLD comes off the
|
||||
// RTCPeerConnection's operations chain (not ahead of going on it), but
|
||||
// this is too difficult to shim. Instead, this shim only covers the
|
||||
// common case where the operations chain is empty. This is imperfect, but
|
||||
// should cover many cases. Rationale: Even if we can't reduce the glare
|
||||
// window to zero on imperfect implementations, there's value in tapping
|
||||
// into the perfect negotiation pattern that several browsers support.
|
||||
desc = {
|
||||
type: desc.type,
|
||||
sdp: desc.sdp
|
||||
};
|
||||
if (!desc.type) {
|
||||
switch (this.signalingState) {
|
||||
case 'stable':
|
||||
case 'have-local-offer':
|
||||
case 'have-remote-pranswer':
|
||||
desc.type = 'offer';
|
||||
break;
|
||||
default:
|
||||
desc.type = 'answer';
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (desc.sdp || desc.type !== 'offer' && desc.type !== 'answer') {
|
||||
return nativeSetLocalDescription.apply(this, [desc]);
|
||||
}
|
||||
var func = desc.type === 'offer' ? this.createOffer : this.createAnswer;
|
||||
return func.apply(this).then(function (d) {
|
||||
return nativeSetLocalDescription.apply(_this, [d]);
|
||||
});
|
||||
};
|
||||
}
|
318
node_modules/webrtc-adapter/dist/firefox/firefox_shim.js
generated
vendored
Normal file
318
node_modules/webrtc-adapter/dist/firefox/firefox_shim.js
generated
vendored
Normal file
@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.shimAddTransceiver = shimAddTransceiver;
|
||||
exports.shimCreateAnswer = shimCreateAnswer;
|
||||
exports.shimCreateOffer = shimCreateOffer;
|
||||
Object.defineProperty(exports, "shimGetDisplayMedia", {
|
||||
enumerable: true,
|
||||
get: function get() {
|
||||
return _getdisplaymedia.shimGetDisplayMedia;
|
||||
}
|
||||
});
|
||||
exports.shimGetParameters = shimGetParameters;
|
||||
Object.defineProperty(exports, "shimGetUserMedia", {
|
||||
enumerable: true,
|
||||
get: function get() {
|
||||
return _getusermedia.shimGetUserMedia;
|
||||
}
|
||||
});
|
||||
exports.shimOnTrack = shimOnTrack;
|
||||
exports.shimPeerConnection = shimPeerConnection;
|
||||
exports.shimRTCDataChannel = shimRTCDataChannel;
|
||||
exports.shimReceiverGetStats = shimReceiverGetStats;
|
||||
exports.shimRemoveStream = shimRemoveStream;
|
||||
exports.shimSenderGetStats = shimSenderGetStats;
|
||||
var utils = _interopRequireWildcard(require("../utils"));
|
||||
var _getusermedia = require("./getusermedia");
|
||||
var _getdisplaymedia = require("./getdisplaymedia");
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
||||
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
||||
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
||||
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
||||
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
||||
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
||||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
|
||||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
||||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
||||
function shimOnTrack(window) {
|
||||
if (_typeof(window) === 'object' && window.RTCTrackEvent && 'receiver' in window.RTCTrackEvent.prototype && !('transceiver' in window.RTCTrackEvent.prototype)) {
|
||||
Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {
|
||||
get: function get() {
|
||||
return {
|
||||
receiver: this.receiver
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
function shimPeerConnection(window, browserDetails) {
|
||||
if (_typeof(window) !== 'object' || !(window.RTCPeerConnection || window.mozRTCPeerConnection)) {
|
||||
return; // probably media.peerconnection.enabled=false in about:config
|
||||
}
|
||||
|
||||
if (!window.RTCPeerConnection && window.mozRTCPeerConnection) {
|
||||
// very basic support for old versions.
|
||||
window.RTCPeerConnection = window.mozRTCPeerConnection;
|
||||
}
|
||||
if (browserDetails.version < 53) {
|
||||
// shim away need for obsolete RTCIceCandidate/RTCSessionDescription.
|
||||
['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'].forEach(function (method) {
|
||||
var nativeMethod = window.RTCPeerConnection.prototype[method];
|
||||
var methodObj = _defineProperty({}, method, function () {
|
||||
arguments[0] = new (method === 'addIceCandidate' ? window.RTCIceCandidate : window.RTCSessionDescription)(arguments[0]);
|
||||
return nativeMethod.apply(this, arguments);
|
||||
});
|
||||
window.RTCPeerConnection.prototype[method] = methodObj[method];
|
||||
});
|
||||
}
|
||||
var modernStatsTypes = {
|
||||
inboundrtp: 'inbound-rtp',
|
||||
outboundrtp: 'outbound-rtp',
|
||||
candidatepair: 'candidate-pair',
|
||||
localcandidate: 'local-candidate',
|
||||
remotecandidate: 'remote-candidate'
|
||||
};
|
||||
var nativeGetStats = window.RTCPeerConnection.prototype.getStats;
|
||||
window.RTCPeerConnection.prototype.getStats = function getStats() {
|
||||
var _arguments = Array.prototype.slice.call(arguments),
|
||||
selector = _arguments[0],
|
||||
onSucc = _arguments[1],
|
||||
onErr = _arguments[2];
|
||||
return nativeGetStats.apply(this, [selector || null]).then(function (stats) {
|
||||
if (browserDetails.version < 53 && !onSucc) {
|
||||
// Shim only promise getStats with spec-hyphens in type names
|
||||
// Leave callback version alone; misc old uses of forEach before Map
|
||||
try {
|
||||
stats.forEach(function (stat) {
|
||||
stat.type = modernStatsTypes[stat.type] || stat.type;
|
||||
});
|
||||
} catch (e) {
|
||||
if (e.name !== 'TypeError') {
|
||||
throw e;
|
||||
}
|
||||
// Avoid TypeError: "type" is read-only, in old versions. 34-43ish
|
||||
stats.forEach(function (stat, i) {
|
||||
stats.set(i, Object.assign({}, stat, {
|
||||
type: modernStatsTypes[stat.type] || stat.type
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
return stats;
|
||||
}).then(onSucc, onErr);
|
||||
};
|
||||
}
|
||||
function shimSenderGetStats(window) {
|
||||
if (!(_typeof(window) === 'object' && window.RTCPeerConnection && window.RTCRtpSender)) {
|
||||
return;
|
||||
}
|
||||
if (window.RTCRtpSender && 'getStats' in window.RTCRtpSender.prototype) {
|
||||
return;
|
||||
}
|
||||
var origGetSenders = window.RTCPeerConnection.prototype.getSenders;
|
||||
if (origGetSenders) {
|
||||
window.RTCPeerConnection.prototype.getSenders = function getSenders() {
|
||||
var _this = this;
|
||||
var senders = origGetSenders.apply(this, []);
|
||||
senders.forEach(function (sender) {
|
||||
return sender._pc = _this;
|
||||
});
|
||||
return senders;
|
||||
};
|
||||
}
|
||||
var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
|
||||
if (origAddTrack) {
|
||||
window.RTCPeerConnection.prototype.addTrack = function addTrack() {
|
||||
var sender = origAddTrack.apply(this, arguments);
|
||||
sender._pc = this;
|
||||
return sender;
|
||||
};
|
||||
}
|
||||
window.RTCRtpSender.prototype.getStats = function getStats() {
|
||||
return this.track ? this._pc.getStats(this.track) : Promise.resolve(new Map());
|
||||
};
|
||||
}
|
||||
function shimReceiverGetStats(window) {
|
||||
if (!(_typeof(window) === 'object' && window.RTCPeerConnection && window.RTCRtpSender)) {
|
||||
return;
|
||||
}
|
||||
if (window.RTCRtpSender && 'getStats' in window.RTCRtpReceiver.prototype) {
|
||||
return;
|
||||
}
|
||||
var origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;
|
||||
if (origGetReceivers) {
|
||||
window.RTCPeerConnection.prototype.getReceivers = function getReceivers() {
|
||||
var _this2 = this;
|
||||
var receivers = origGetReceivers.apply(this, []);
|
||||
receivers.forEach(function (receiver) {
|
||||
return receiver._pc = _this2;
|
||||
});
|
||||
return receivers;
|
||||
};
|
||||
}
|
||||
utils.wrapPeerConnectionEvent(window, 'track', function (e) {
|
||||
e.receiver._pc = e.srcElement;
|
||||
return e;
|
||||
});
|
||||
window.RTCRtpReceiver.prototype.getStats = function getStats() {
|
||||
return this._pc.getStats(this.track);
|
||||
};
|
||||
}
|
||||
function shimRemoveStream(window) {
|
||||
if (!window.RTCPeerConnection || 'removeStream' in window.RTCPeerConnection.prototype) {
|
||||
return;
|
||||
}
|
||||
window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
|
||||
var _this3 = this;
|
||||
utils.deprecated('removeStream', 'removeTrack');
|
||||
this.getSenders().forEach(function (sender) {
|
||||
if (sender.track && stream.getTracks().includes(sender.track)) {
|
||||
_this3.removeTrack(sender);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
function shimRTCDataChannel(window) {
|
||||
// rename DataChannel to RTCDataChannel (native fix in FF60):
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1173851
|
||||
if (window.DataChannel && !window.RTCDataChannel) {
|
||||
window.RTCDataChannel = window.DataChannel;
|
||||
}
|
||||
}
|
||||
function shimAddTransceiver(window) {
|
||||
// https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647
|
||||
// Firefox ignores the init sendEncodings options passed to addTransceiver
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1396918
|
||||
if (!(_typeof(window) === 'object' && window.RTCPeerConnection)) {
|
||||
return;
|
||||
}
|
||||
var origAddTransceiver = window.RTCPeerConnection.prototype.addTransceiver;
|
||||
if (origAddTransceiver) {
|
||||
window.RTCPeerConnection.prototype.addTransceiver = function addTransceiver() {
|
||||
this.setParametersPromises = [];
|
||||
// WebIDL input coercion and validation
|
||||
var sendEncodings = arguments[1] && arguments[1].sendEncodings;
|
||||
if (sendEncodings === undefined) {
|
||||
sendEncodings = [];
|
||||
}
|
||||
sendEncodings = _toConsumableArray(sendEncodings);
|
||||
var shouldPerformCheck = sendEncodings.length > 0;
|
||||
if (shouldPerformCheck) {
|
||||
// If sendEncodings params are provided, validate grammar
|
||||
sendEncodings.forEach(function (encodingParam) {
|
||||
if ('rid' in encodingParam) {
|
||||
var ridRegex = /^[a-z0-9]{0,16}$/i;
|
||||
if (!ridRegex.test(encodingParam.rid)) {
|
||||
throw new TypeError('Invalid RID value provided.');
|
||||
}
|
||||
}
|
||||
if ('scaleResolutionDownBy' in encodingParam) {
|
||||
if (!(parseFloat(encodingParam.scaleResolutionDownBy) >= 1.0)) {
|
||||
throw new RangeError('scale_resolution_down_by must be >= 1.0');
|
||||
}
|
||||
}
|
||||
if ('maxFramerate' in encodingParam) {
|
||||
if (!(parseFloat(encodingParam.maxFramerate) >= 0)) {
|
||||
throw new RangeError('max_framerate must be >= 0.0');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
var transceiver = origAddTransceiver.apply(this, arguments);
|
||||
if (shouldPerformCheck) {
|
||||
// Check if the init options were applied. If not we do this in an
|
||||
// asynchronous way and save the promise reference in a global object.
|
||||
// This is an ugly hack, but at the same time is way more robust than
|
||||
// checking the sender parameters before and after the createOffer
|
||||
// Also note that after the createoffer we are not 100% sure that
|
||||
// the params were asynchronously applied so we might miss the
|
||||
// opportunity to recreate offer.
|
||||
var sender = transceiver.sender;
|
||||
var params = sender.getParameters();
|
||||
if (!('encodings' in params) ||
|
||||
// Avoid being fooled by patched getParameters() below.
|
||||
params.encodings.length === 1 && Object.keys(params.encodings[0]).length === 0) {
|
||||
params.encodings = sendEncodings;
|
||||
sender.sendEncodings = sendEncodings;
|
||||
this.setParametersPromises.push(sender.setParameters(params).then(function () {
|
||||
delete sender.sendEncodings;
|
||||
})["catch"](function () {
|
||||
delete sender.sendEncodings;
|
||||
}));
|
||||
}
|
||||
}
|
||||
return transceiver;
|
||||
};
|
||||
}
|
||||
}
|
||||
function shimGetParameters(window) {
|
||||
if (!(_typeof(window) === 'object' && window.RTCRtpSender)) {
|
||||
return;
|
||||
}
|
||||
var origGetParameters = window.RTCRtpSender.prototype.getParameters;
|
||||
if (origGetParameters) {
|
||||
window.RTCRtpSender.prototype.getParameters = function getParameters() {
|
||||
var params = origGetParameters.apply(this, arguments);
|
||||
if (!('encodings' in params)) {
|
||||
params.encodings = [].concat(this.sendEncodings || [{}]);
|
||||
}
|
||||
return params;
|
||||
};
|
||||
}
|
||||
}
|
||||
function shimCreateOffer(window) {
|
||||
// https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647
|
||||
// Firefox ignores the init sendEncodings options passed to addTransceiver
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1396918
|
||||
if (!(_typeof(window) === 'object' && window.RTCPeerConnection)) {
|
||||
return;
|
||||
}
|
||||
var origCreateOffer = window.RTCPeerConnection.prototype.createOffer;
|
||||
window.RTCPeerConnection.prototype.createOffer = function createOffer() {
|
||||
var _arguments2 = arguments,
|
||||
_this4 = this;
|
||||
if (this.setParametersPromises && this.setParametersPromises.length) {
|
||||
return Promise.all(this.setParametersPromises).then(function () {
|
||||
return origCreateOffer.apply(_this4, _arguments2);
|
||||
})["finally"](function () {
|
||||
_this4.setParametersPromises = [];
|
||||
});
|
||||
}
|
||||
return origCreateOffer.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
function shimCreateAnswer(window) {
|
||||
// https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647
|
||||
// Firefox ignores the init sendEncodings options passed to addTransceiver
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1396918
|
||||
if (!(_typeof(window) === 'object' && window.RTCPeerConnection)) {
|
||||
return;
|
||||
}
|
||||
var origCreateAnswer = window.RTCPeerConnection.prototype.createAnswer;
|
||||
window.RTCPeerConnection.prototype.createAnswer = function createAnswer() {
|
||||
var _arguments3 = arguments,
|
||||
_this5 = this;
|
||||
if (this.setParametersPromises && this.setParametersPromises.length) {
|
||||
return Promise.all(this.setParametersPromises).then(function () {
|
||||
return origCreateAnswer.apply(_this5, _arguments3);
|
||||
})["finally"](function () {
|
||||
_this5.setParametersPromises = [];
|
||||
});
|
||||
}
|
||||
return origCreateAnswer.apply(this, arguments);
|
||||
};
|
||||
}
|
39
node_modules/webrtc-adapter/dist/firefox/getdisplaymedia.js
generated
vendored
Normal file
39
node_modules/webrtc-adapter/dist/firefox/getdisplaymedia.js
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.shimGetDisplayMedia = shimGetDisplayMedia;
|
||||
function shimGetDisplayMedia(window, preferredMediaSource) {
|
||||
if (window.navigator.mediaDevices && 'getDisplayMedia' in window.navigator.mediaDevices) {
|
||||
return;
|
||||
}
|
||||
if (!window.navigator.mediaDevices) {
|
||||
return;
|
||||
}
|
||||
window.navigator.mediaDevices.getDisplayMedia = function getDisplayMedia(constraints) {
|
||||
if (!(constraints && constraints.video)) {
|
||||
var err = new DOMException('getDisplayMedia without video ' + 'constraints is undefined');
|
||||
err.name = 'NotFoundError';
|
||||
// from https://heycam.github.io/webidl/#idl-DOMException-error-names
|
||||
err.code = 8;
|
||||
return Promise.reject(err);
|
||||
}
|
||||
if (constraints.video === true) {
|
||||
constraints.video = {
|
||||
mediaSource: preferredMediaSource
|
||||
};
|
||||
} else {
|
||||
constraints.video.mediaSource = preferredMediaSource;
|
||||
}
|
||||
return window.navigator.mediaDevices.getUserMedia(constraints);
|
||||
};
|
||||
}
|
64
node_modules/webrtc-adapter/dist/firefox/getusermedia.js
generated
vendored
Normal file
64
node_modules/webrtc-adapter/dist/firefox/getusermedia.js
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.shimGetUserMedia = shimGetUserMedia;
|
||||
var utils = _interopRequireWildcard(require("../utils"));
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
||||
function shimGetUserMedia(window, browserDetails) {
|
||||
var navigator = window && window.navigator;
|
||||
var MediaStreamTrack = window && window.MediaStreamTrack;
|
||||
navigator.getUserMedia = function (constraints, onSuccess, onError) {
|
||||
// Replace Firefox 44+'s deprecation warning with unprefixed version.
|
||||
utils.deprecated('navigator.getUserMedia', 'navigator.mediaDevices.getUserMedia');
|
||||
navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError);
|
||||
};
|
||||
if (!(browserDetails.version > 55 && 'autoGainControl' in navigator.mediaDevices.getSupportedConstraints())) {
|
||||
var remap = function remap(obj, a, b) {
|
||||
if (a in obj && !(b in obj)) {
|
||||
obj[b] = obj[a];
|
||||
delete obj[a];
|
||||
}
|
||||
};
|
||||
var nativeGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
|
||||
navigator.mediaDevices.getUserMedia = function (c) {
|
||||
if (_typeof(c) === 'object' && _typeof(c.audio) === 'object') {
|
||||
c = JSON.parse(JSON.stringify(c));
|
||||
remap(c.audio, 'autoGainControl', 'mozAutoGainControl');
|
||||
remap(c.audio, 'noiseSuppression', 'mozNoiseSuppression');
|
||||
}
|
||||
return nativeGetUserMedia(c);
|
||||
};
|
||||
if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) {
|
||||
var nativeGetSettings = MediaStreamTrack.prototype.getSettings;
|
||||
MediaStreamTrack.prototype.getSettings = function () {
|
||||
var obj = nativeGetSettings.apply(this, arguments);
|
||||
remap(obj, 'mozAutoGainControl', 'autoGainControl');
|
||||
remap(obj, 'mozNoiseSuppression', 'noiseSuppression');
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
if (MediaStreamTrack && MediaStreamTrack.prototype.applyConstraints) {
|
||||
var nativeApplyConstraints = MediaStreamTrack.prototype.applyConstraints;
|
||||
MediaStreamTrack.prototype.applyConstraints = function (c) {
|
||||
if (this.kind === 'audio' && _typeof(c) === 'object') {
|
||||
c = JSON.parse(JSON.stringify(c));
|
||||
remap(c, 'autoGainControl', 'mozAutoGainControl');
|
||||
remap(c, 'noiseSuppression', 'mozNoiseSuppression');
|
||||
}
|
||||
return nativeApplyConstraints.apply(this, [c]);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
346
node_modules/webrtc-adapter/dist/safari/safari_shim.js
generated
vendored
Normal file
346
node_modules/webrtc-adapter/dist/safari/safari_shim.js
generated
vendored
Normal file
@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.shimAudioContext = shimAudioContext;
|
||||
exports.shimCallbacksAPI = shimCallbacksAPI;
|
||||
exports.shimConstraints = shimConstraints;
|
||||
exports.shimCreateOfferLegacy = shimCreateOfferLegacy;
|
||||
exports.shimGetUserMedia = shimGetUserMedia;
|
||||
exports.shimLocalStreamsAPI = shimLocalStreamsAPI;
|
||||
exports.shimRTCIceServerUrls = shimRTCIceServerUrls;
|
||||
exports.shimRemoteStreamsAPI = shimRemoteStreamsAPI;
|
||||
exports.shimTrackEventTransceiver = shimTrackEventTransceiver;
|
||||
var utils = _interopRequireWildcard(require("../utils"));
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
||||
function shimLocalStreamsAPI(window) {
|
||||
if (_typeof(window) !== 'object' || !window.RTCPeerConnection) {
|
||||
return;
|
||||
}
|
||||
if (!('getLocalStreams' in window.RTCPeerConnection.prototype)) {
|
||||
window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() {
|
||||
if (!this._localStreams) {
|
||||
this._localStreams = [];
|
||||
}
|
||||
return this._localStreams;
|
||||
};
|
||||
}
|
||||
if (!('addStream' in window.RTCPeerConnection.prototype)) {
|
||||
var _addTrack = window.RTCPeerConnection.prototype.addTrack;
|
||||
window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
|
||||
var _this = this;
|
||||
if (!this._localStreams) {
|
||||
this._localStreams = [];
|
||||
}
|
||||
if (!this._localStreams.includes(stream)) {
|
||||
this._localStreams.push(stream);
|
||||
}
|
||||
// Try to emulate Chrome's behaviour of adding in audio-video order.
|
||||
// Safari orders by track id.
|
||||
stream.getAudioTracks().forEach(function (track) {
|
||||
return _addTrack.call(_this, track, stream);
|
||||
});
|
||||
stream.getVideoTracks().forEach(function (track) {
|
||||
return _addTrack.call(_this, track, stream);
|
||||
});
|
||||
};
|
||||
window.RTCPeerConnection.prototype.addTrack = function addTrack(track) {
|
||||
var _this2 = this;
|
||||
for (var _len = arguments.length, streams = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
||||
streams[_key - 1] = arguments[_key];
|
||||
}
|
||||
if (streams) {
|
||||
streams.forEach(function (stream) {
|
||||
if (!_this2._localStreams) {
|
||||
_this2._localStreams = [stream];
|
||||
} else if (!_this2._localStreams.includes(stream)) {
|
||||
_this2._localStreams.push(stream);
|
||||
}
|
||||
});
|
||||
}
|
||||
return _addTrack.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
if (!('removeStream' in window.RTCPeerConnection.prototype)) {
|
||||
window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
|
||||
var _this3 = this;
|
||||
if (!this._localStreams) {
|
||||
this._localStreams = [];
|
||||
}
|
||||
var index = this._localStreams.indexOf(stream);
|
||||
if (index === -1) {
|
||||
return;
|
||||
}
|
||||
this._localStreams.splice(index, 1);
|
||||
var tracks = stream.getTracks();
|
||||
this.getSenders().forEach(function (sender) {
|
||||
if (tracks.includes(sender.track)) {
|
||||
_this3.removeTrack(sender);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
function shimRemoteStreamsAPI(window) {
|
||||
if (_typeof(window) !== 'object' || !window.RTCPeerConnection) {
|
||||
return;
|
||||
}
|
||||
if (!('getRemoteStreams' in window.RTCPeerConnection.prototype)) {
|
||||
window.RTCPeerConnection.prototype.getRemoteStreams = function getRemoteStreams() {
|
||||
return this._remoteStreams ? this._remoteStreams : [];
|
||||
};
|
||||
}
|
||||
if (!('onaddstream' in window.RTCPeerConnection.prototype)) {
|
||||
Object.defineProperty(window.RTCPeerConnection.prototype, 'onaddstream', {
|
||||
get: function get() {
|
||||
return this._onaddstream;
|
||||
},
|
||||
set: function set(f) {
|
||||
var _this4 = this;
|
||||
if (this._onaddstream) {
|
||||
this.removeEventListener('addstream', this._onaddstream);
|
||||
this.removeEventListener('track', this._onaddstreampoly);
|
||||
}
|
||||
this.addEventListener('addstream', this._onaddstream = f);
|
||||
this.addEventListener('track', this._onaddstreampoly = function (e) {
|
||||
e.streams.forEach(function (stream) {
|
||||
if (!_this4._remoteStreams) {
|
||||
_this4._remoteStreams = [];
|
||||
}
|
||||
if (_this4._remoteStreams.includes(stream)) {
|
||||
return;
|
||||
}
|
||||
_this4._remoteStreams.push(stream);
|
||||
var event = new Event('addstream');
|
||||
event.stream = stream;
|
||||
_this4.dispatchEvent(event);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
var origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription;
|
||||
window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() {
|
||||
var pc = this;
|
||||
if (!this._onaddstreampoly) {
|
||||
this.addEventListener('track', this._onaddstreampoly = function (e) {
|
||||
e.streams.forEach(function (stream) {
|
||||
if (!pc._remoteStreams) {
|
||||
pc._remoteStreams = [];
|
||||
}
|
||||
if (pc._remoteStreams.indexOf(stream) >= 0) {
|
||||
return;
|
||||
}
|
||||
pc._remoteStreams.push(stream);
|
||||
var event = new Event('addstream');
|
||||
event.stream = stream;
|
||||
pc.dispatchEvent(event);
|
||||
});
|
||||
});
|
||||
}
|
||||
return origSetRemoteDescription.apply(pc, arguments);
|
||||
};
|
||||
}
|
||||
}
|
||||
function shimCallbacksAPI(window) {
|
||||
if (_typeof(window) !== 'object' || !window.RTCPeerConnection) {
|
||||
return;
|
||||
}
|
||||
var prototype = window.RTCPeerConnection.prototype;
|
||||
var origCreateOffer = prototype.createOffer;
|
||||
var origCreateAnswer = prototype.createAnswer;
|
||||
var setLocalDescription = prototype.setLocalDescription;
|
||||
var setRemoteDescription = prototype.setRemoteDescription;
|
||||
var addIceCandidate = prototype.addIceCandidate;
|
||||
prototype.createOffer = function createOffer(successCallback, failureCallback) {
|
||||
var options = arguments.length >= 2 ? arguments[2] : arguments[0];
|
||||
var promise = origCreateOffer.apply(this, [options]);
|
||||
if (!failureCallback) {
|
||||
return promise;
|
||||
}
|
||||
promise.then(successCallback, failureCallback);
|
||||
return Promise.resolve();
|
||||
};
|
||||
prototype.createAnswer = function createAnswer(successCallback, failureCallback) {
|
||||
var options = arguments.length >= 2 ? arguments[2] : arguments[0];
|
||||
var promise = origCreateAnswer.apply(this, [options]);
|
||||
if (!failureCallback) {
|
||||
return promise;
|
||||
}
|
||||
promise.then(successCallback, failureCallback);
|
||||
return Promise.resolve();
|
||||
};
|
||||
var withCallback = function withCallback(description, successCallback, failureCallback) {
|
||||
var promise = setLocalDescription.apply(this, [description]);
|
||||
if (!failureCallback) {
|
||||
return promise;
|
||||
}
|
||||
promise.then(successCallback, failureCallback);
|
||||
return Promise.resolve();
|
||||
};
|
||||
prototype.setLocalDescription = withCallback;
|
||||
withCallback = function withCallback(description, successCallback, failureCallback) {
|
||||
var promise = setRemoteDescription.apply(this, [description]);
|
||||
if (!failureCallback) {
|
||||
return promise;
|
||||
}
|
||||
promise.then(successCallback, failureCallback);
|
||||
return Promise.resolve();
|
||||
};
|
||||
prototype.setRemoteDescription = withCallback;
|
||||
withCallback = function withCallback(candidate, successCallback, failureCallback) {
|
||||
var promise = addIceCandidate.apply(this, [candidate]);
|
||||
if (!failureCallback) {
|
||||
return promise;
|
||||
}
|
||||
promise.then(successCallback, failureCallback);
|
||||
return Promise.resolve();
|
||||
};
|
||||
prototype.addIceCandidate = withCallback;
|
||||
}
|
||||
function shimGetUserMedia(window) {
|
||||
var navigator = window && window.navigator;
|
||||
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
|
||||
// shim not needed in Safari 12.1
|
||||
var mediaDevices = navigator.mediaDevices;
|
||||
var _getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices);
|
||||
navigator.mediaDevices.getUserMedia = function (constraints) {
|
||||
return _getUserMedia(shimConstraints(constraints));
|
||||
};
|
||||
}
|
||||
if (!navigator.getUserMedia && navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
|
||||
navigator.getUserMedia = function getUserMedia(constraints, cb, errcb) {
|
||||
navigator.mediaDevices.getUserMedia(constraints).then(cb, errcb);
|
||||
}.bind(navigator);
|
||||
}
|
||||
}
|
||||
function shimConstraints(constraints) {
|
||||
if (constraints && constraints.video !== undefined) {
|
||||
return Object.assign({}, constraints, {
|
||||
video: utils.compactObject(constraints.video)
|
||||
});
|
||||
}
|
||||
return constraints;
|
||||
}
|
||||
function shimRTCIceServerUrls(window) {
|
||||
if (!window.RTCPeerConnection) {
|
||||
return;
|
||||
}
|
||||
// migrate from non-spec RTCIceServer.url to RTCIceServer.urls
|
||||
var OrigPeerConnection = window.RTCPeerConnection;
|
||||
window.RTCPeerConnection = function RTCPeerConnection(pcConfig, pcConstraints) {
|
||||
if (pcConfig && pcConfig.iceServers) {
|
||||
var newIceServers = [];
|
||||
for (var i = 0; i < pcConfig.iceServers.length; i++) {
|
||||
var server = pcConfig.iceServers[i];
|
||||
if (server.urls === undefined && server.url) {
|
||||
utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls');
|
||||
server = JSON.parse(JSON.stringify(server));
|
||||
server.urls = server.url;
|
||||
delete server.url;
|
||||
newIceServers.push(server);
|
||||
} else {
|
||||
newIceServers.push(pcConfig.iceServers[i]);
|
||||
}
|
||||
}
|
||||
pcConfig.iceServers = newIceServers;
|
||||
}
|
||||
return new OrigPeerConnection(pcConfig, pcConstraints);
|
||||
};
|
||||
window.RTCPeerConnection.prototype = OrigPeerConnection.prototype;
|
||||
// wrap static methods. Currently just generateCertificate.
|
||||
if ('generateCertificate' in OrigPeerConnection) {
|
||||
Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {
|
||||
get: function get() {
|
||||
return OrigPeerConnection.generateCertificate;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
function shimTrackEventTransceiver(window) {
|
||||
// Add event.transceiver member over deprecated event.receiver
|
||||
if (_typeof(window) === 'object' && window.RTCTrackEvent && 'receiver' in window.RTCTrackEvent.prototype && !('transceiver' in window.RTCTrackEvent.prototype)) {
|
||||
Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {
|
||||
get: function get() {
|
||||
return {
|
||||
receiver: this.receiver
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
function shimCreateOfferLegacy(window) {
|
||||
var origCreateOffer = window.RTCPeerConnection.prototype.createOffer;
|
||||
window.RTCPeerConnection.prototype.createOffer = function createOffer(offerOptions) {
|
||||
if (offerOptions) {
|
||||
if (typeof offerOptions.offerToReceiveAudio !== 'undefined') {
|
||||
// support bit values
|
||||
offerOptions.offerToReceiveAudio = !!offerOptions.offerToReceiveAudio;
|
||||
}
|
||||
var audioTransceiver = this.getTransceivers().find(function (transceiver) {
|
||||
return transceiver.receiver.track.kind === 'audio';
|
||||
});
|
||||
if (offerOptions.offerToReceiveAudio === false && audioTransceiver) {
|
||||
if (audioTransceiver.direction === 'sendrecv') {
|
||||
if (audioTransceiver.setDirection) {
|
||||
audioTransceiver.setDirection('sendonly');
|
||||
} else {
|
||||
audioTransceiver.direction = 'sendonly';
|
||||
}
|
||||
} else if (audioTransceiver.direction === 'recvonly') {
|
||||
if (audioTransceiver.setDirection) {
|
||||
audioTransceiver.setDirection('inactive');
|
||||
} else {
|
||||
audioTransceiver.direction = 'inactive';
|
||||
}
|
||||
}
|
||||
} else if (offerOptions.offerToReceiveAudio === true && !audioTransceiver) {
|
||||
this.addTransceiver('audio', {
|
||||
direction: 'recvonly'
|
||||
});
|
||||
}
|
||||
if (typeof offerOptions.offerToReceiveVideo !== 'undefined') {
|
||||
// support bit values
|
||||
offerOptions.offerToReceiveVideo = !!offerOptions.offerToReceiveVideo;
|
||||
}
|
||||
var videoTransceiver = this.getTransceivers().find(function (transceiver) {
|
||||
return transceiver.receiver.track.kind === 'video';
|
||||
});
|
||||
if (offerOptions.offerToReceiveVideo === false && videoTransceiver) {
|
||||
if (videoTransceiver.direction === 'sendrecv') {
|
||||
if (videoTransceiver.setDirection) {
|
||||
videoTransceiver.setDirection('sendonly');
|
||||
} else {
|
||||
videoTransceiver.direction = 'sendonly';
|
||||
}
|
||||
} else if (videoTransceiver.direction === 'recvonly') {
|
||||
if (videoTransceiver.setDirection) {
|
||||
videoTransceiver.setDirection('inactive');
|
||||
} else {
|
||||
videoTransceiver.direction = 'inactive';
|
||||
}
|
||||
}
|
||||
} else if (offerOptions.offerToReceiveVideo === true && !videoTransceiver) {
|
||||
this.addTransceiver('video', {
|
||||
direction: 'recvonly'
|
||||
});
|
||||
}
|
||||
}
|
||||
return origCreateOffer.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
function shimAudioContext(window) {
|
||||
if (_typeof(window) !== 'object' || window.AudioContext) {
|
||||
return;
|
||||
}
|
||||
window.AudioContext = window.webkitAudioContext;
|
||||
}
|
260
node_modules/webrtc-adapter/dist/utils.js
generated
vendored
Normal file
260
node_modules/webrtc-adapter/dist/utils.js
generated
vendored
Normal file
@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.compactObject = compactObject;
|
||||
exports.deprecated = deprecated;
|
||||
exports.detectBrowser = detectBrowser;
|
||||
exports.disableLog = disableLog;
|
||||
exports.disableWarnings = disableWarnings;
|
||||
exports.extractVersion = extractVersion;
|
||||
exports.filterStats = filterStats;
|
||||
exports.log = log;
|
||||
exports.walkStats = walkStats;
|
||||
exports.wrapPeerConnectionEvent = wrapPeerConnectionEvent;
|
||||
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
|
||||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
||||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
||||
var logDisabled_ = true;
|
||||
var deprecationWarnings_ = true;
|
||||
|
||||
/**
|
||||
* Extract browser version out of the provided user agent string.
|
||||
*
|
||||
* @param {!string} uastring userAgent string.
|
||||
* @param {!string} expr Regular expression used as match criteria.
|
||||
* @param {!number} pos position in the version string to be returned.
|
||||
* @return {!number} browser version.
|
||||
*/
|
||||
function extractVersion(uastring, expr, pos) {
|
||||
var match = uastring.match(expr);
|
||||
return match && match.length >= pos && parseInt(match[pos], 10);
|
||||
}
|
||||
|
||||
// Wraps the peerconnection event eventNameToWrap in a function
|
||||
// which returns the modified event object (or false to prevent
|
||||
// the event).
|
||||
function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) {
|
||||
if (!window.RTCPeerConnection) {
|
||||
return;
|
||||
}
|
||||
var proto = window.RTCPeerConnection.prototype;
|
||||
var nativeAddEventListener = proto.addEventListener;
|
||||
proto.addEventListener = function (nativeEventName, cb) {
|
||||
if (nativeEventName !== eventNameToWrap) {
|
||||
return nativeAddEventListener.apply(this, arguments);
|
||||
}
|
||||
var wrappedCallback = function wrappedCallback(e) {
|
||||
var modifiedEvent = wrapper(e);
|
||||
if (modifiedEvent) {
|
||||
if (cb.handleEvent) {
|
||||
cb.handleEvent(modifiedEvent);
|
||||
} else {
|
||||
cb(modifiedEvent);
|
||||
}
|
||||
}
|
||||
};
|
||||
this._eventMap = this._eventMap || {};
|
||||
if (!this._eventMap[eventNameToWrap]) {
|
||||
this._eventMap[eventNameToWrap] = new Map();
|
||||
}
|
||||
this._eventMap[eventNameToWrap].set(cb, wrappedCallback);
|
||||
return nativeAddEventListener.apply(this, [nativeEventName, wrappedCallback]);
|
||||
};
|
||||
var nativeRemoveEventListener = proto.removeEventListener;
|
||||
proto.removeEventListener = function (nativeEventName, cb) {
|
||||
if (nativeEventName !== eventNameToWrap || !this._eventMap || !this._eventMap[eventNameToWrap]) {
|
||||
return nativeRemoveEventListener.apply(this, arguments);
|
||||
}
|
||||
if (!this._eventMap[eventNameToWrap].has(cb)) {
|
||||
return nativeRemoveEventListener.apply(this, arguments);
|
||||
}
|
||||
var unwrappedCb = this._eventMap[eventNameToWrap].get(cb);
|
||||
this._eventMap[eventNameToWrap]["delete"](cb);
|
||||
if (this._eventMap[eventNameToWrap].size === 0) {
|
||||
delete this._eventMap[eventNameToWrap];
|
||||
}
|
||||
if (Object.keys(this._eventMap).length === 0) {
|
||||
delete this._eventMap;
|
||||
}
|
||||
return nativeRemoveEventListener.apply(this, [nativeEventName, unwrappedCb]);
|
||||
};
|
||||
Object.defineProperty(proto, 'on' + eventNameToWrap, {
|
||||
get: function get() {
|
||||
return this['_on' + eventNameToWrap];
|
||||
},
|
||||
set: function set(cb) {
|
||||
if (this['_on' + eventNameToWrap]) {
|
||||
this.removeEventListener(eventNameToWrap, this['_on' + eventNameToWrap]);
|
||||
delete this['_on' + eventNameToWrap];
|
||||
}
|
||||
if (cb) {
|
||||
this.addEventListener(eventNameToWrap, this['_on' + eventNameToWrap] = cb);
|
||||
}
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
function disableLog(bool) {
|
||||
if (typeof bool !== 'boolean') {
|
||||
return new Error('Argument type: ' + _typeof(bool) + '. Please use a boolean.');
|
||||
}
|
||||
logDisabled_ = bool;
|
||||
return bool ? 'adapter.js logging disabled' : 'adapter.js logging enabled';
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable or enable deprecation warnings
|
||||
* @param {!boolean} bool set to true to disable warnings.
|
||||
*/
|
||||
function disableWarnings(bool) {
|
||||
if (typeof bool !== 'boolean') {
|
||||
return new Error('Argument type: ' + _typeof(bool) + '. Please use a boolean.');
|
||||
}
|
||||
deprecationWarnings_ = !bool;
|
||||
return 'adapter.js deprecation warnings ' + (bool ? 'disabled' : 'enabled');
|
||||
}
|
||||
function log() {
|
||||
if ((typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object') {
|
||||
if (logDisabled_) {
|
||||
return;
|
||||
}
|
||||
if (typeof console !== 'undefined' && typeof console.log === 'function') {
|
||||
console.log.apply(console, arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a deprecation warning suggesting the modern and spec-compatible API.
|
||||
*/
|
||||
function deprecated(oldMethod, newMethod) {
|
||||
if (!deprecationWarnings_) {
|
||||
return;
|
||||
}
|
||||
console.warn(oldMethod + ' is deprecated, please use ' + newMethod + ' instead.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Browser detector.
|
||||
*
|
||||
* @return {object} result containing browser and version
|
||||
* properties.
|
||||
*/
|
||||
function detectBrowser(window) {
|
||||
// Returned result object.
|
||||
var result = {
|
||||
browser: null,
|
||||
version: null
|
||||
};
|
||||
|
||||
// Fail early if it's not a browser
|
||||
if (typeof window === 'undefined' || !window.navigator || !window.navigator.userAgent) {
|
||||
result.browser = 'Not a browser.';
|
||||
return result;
|
||||
}
|
||||
var navigator = window.navigator;
|
||||
if (navigator.mozGetUserMedia) {
|
||||
// Firefox.
|
||||
result.browser = 'firefox';
|
||||
result.version = extractVersion(navigator.userAgent, /Firefox\/(\d+)\./, 1);
|
||||
} else if (navigator.webkitGetUserMedia || window.isSecureContext === false && window.webkitRTCPeerConnection) {
|
||||
// Chrome, Chromium, Webview, Opera.
|
||||
// Version matches Chrome/WebRTC version.
|
||||
// Chrome 74 removed webkitGetUserMedia on http as well so we need the
|
||||
// more complicated fallback to webkitRTCPeerConnection.
|
||||
result.browser = 'chrome';
|
||||
result.version = extractVersion(navigator.userAgent, /Chrom(e|ium)\/(\d+)\./, 2);
|
||||
} else if (window.RTCPeerConnection && navigator.userAgent.match(/AppleWebKit\/(\d+)\./)) {
|
||||
// Safari.
|
||||
result.browser = 'safari';
|
||||
result.version = extractVersion(navigator.userAgent, /AppleWebKit\/(\d+)\./, 1);
|
||||
result.supportsUnifiedPlan = window.RTCRtpTransceiver && 'currentDirection' in window.RTCRtpTransceiver.prototype;
|
||||
} else {
|
||||
// Default fallthrough: not supported.
|
||||
result.browser = 'Not a supported browser.';
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if something is an object.
|
||||
*
|
||||
* @param {*} val The something you want to check.
|
||||
* @return true if val is an object, false otherwise.
|
||||
*/
|
||||
function isObject(val) {
|
||||
return Object.prototype.toString.call(val) === '[object Object]';
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all empty objects and undefined values
|
||||
* from a nested object -- an enhanced and vanilla version
|
||||
* of Lodash's `compact`.
|
||||
*/
|
||||
function compactObject(data) {
|
||||
if (!isObject(data)) {
|
||||
return data;
|
||||
}
|
||||
return Object.keys(data).reduce(function (accumulator, key) {
|
||||
var isObj = isObject(data[key]);
|
||||
var value = isObj ? compactObject(data[key]) : data[key];
|
||||
var isEmptyObject = isObj && !Object.keys(value).length;
|
||||
if (value === undefined || isEmptyObject) {
|
||||
return accumulator;
|
||||
}
|
||||
return Object.assign(accumulator, _defineProperty({}, key, value));
|
||||
}, {});
|
||||
}
|
||||
|
||||
/* iterates the stats graph recursively. */
|
||||
function walkStats(stats, base, resultSet) {
|
||||
if (!base || resultSet.has(base.id)) {
|
||||
return;
|
||||
}
|
||||
resultSet.set(base.id, base);
|
||||
Object.keys(base).forEach(function (name) {
|
||||
if (name.endsWith('Id')) {
|
||||
walkStats(stats, stats.get(base[name]), resultSet);
|
||||
} else if (name.endsWith('Ids')) {
|
||||
base[name].forEach(function (id) {
|
||||
walkStats(stats, stats.get(id), resultSet);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* filter getStats for a sender/receiver track. */
|
||||
function filterStats(result, track, outbound) {
|
||||
var streamStatsType = outbound ? 'outbound-rtp' : 'inbound-rtp';
|
||||
var filteredResult = new Map();
|
||||
if (track === null) {
|
||||
return filteredResult;
|
||||
}
|
||||
var trackStats = [];
|
||||
result.forEach(function (value) {
|
||||
if (value.type === 'track' && value.trackIdentifier === track.id) {
|
||||
trackStats.push(value);
|
||||
}
|
||||
});
|
||||
trackStats.forEach(function (trackStat) {
|
||||
result.forEach(function (stats) {
|
||||
if (stats.type === streamStatsType && stats.trackId === trackStat.id) {
|
||||
walkStats(result, stats, filteredResult);
|
||||
}
|
||||
});
|
||||
});
|
||||
return filteredResult;
|
||||
}
|
59
node_modules/webrtc-adapter/index.d.ts
generated
vendored
Normal file
59
node_modules/webrtc-adapter/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
declare module "webrtc-adapter" {
|
||||
interface IBrowserDetails {
|
||||
browser: string;
|
||||
version?: number;
|
||||
supportsUnifiedPlan?: boolean;
|
||||
}
|
||||
|
||||
interface ICommonShim {
|
||||
shimRTCIceCandidate(window: Window): void;
|
||||
shimMaxMessageSize(window: Window): void;
|
||||
shimSendThrowTypeError(window: Window): void;
|
||||
shimConnectionState(window: Window): void;
|
||||
removeAllowExtmapMixed(window: Window): void;
|
||||
}
|
||||
|
||||
interface IChromeShim {
|
||||
shimMediaStream(window: Window): void;
|
||||
shimOnTrack(window: Window): void;
|
||||
shimGetSendersWithDtmf(window: Window): void;
|
||||
shimGetStats(window: Window): void;
|
||||
shimSenderReceiverGetStats(window: Window): void;
|
||||
shimAddTrackRemoveTrackWithNative(window: Window): void;
|
||||
shimAddTrackRemoveTrack(window: Window): void;
|
||||
shimPeerConnection(window: Window): void;
|
||||
fixNegotiationNeeded(window: Window): void;
|
||||
}
|
||||
|
||||
interface IFirefoxShim {
|
||||
shimOnTrack(window: Window): void;
|
||||
shimPeerConnection(window: Window): void;
|
||||
shimSenderGetStats(window: Window): void;
|
||||
shimReceiverGetStats(window: Window): void;
|
||||
shimRemoveStream(window: Window): void;
|
||||
shimRTCDataChannel(window: Window): void;
|
||||
}
|
||||
|
||||
interface ISafariShim {
|
||||
shimLocalStreamsAPI(window: Window): void;
|
||||
shimRemoteStreamsAPI(window: Window): void;
|
||||
shimCallbacksAPI(window: Window): void;
|
||||
shimGetUserMedia(window: Window): void;
|
||||
shimConstraints(constraints: MediaStreamConstraints): void;
|
||||
shimRTCIceServerUrls(window: Window): void;
|
||||
shimTrackEventTransceiver(window: Window): void;
|
||||
shimCreateOfferLegacy(window: Window): void;
|
||||
}
|
||||
|
||||
export interface IAdapter {
|
||||
browserDetails: IBrowserDetails;
|
||||
commonShim: ICommonShim;
|
||||
browserShim: IChromeShim | IFirefoxShim | ISafariShim | undefined;
|
||||
extractVersion(uastring: string, expr: string, pos: number): number;
|
||||
disableLog(disable: boolean): void;
|
||||
disableWarnings(disable: boolean): void;
|
||||
}
|
||||
|
||||
const adapter: IAdapter;
|
||||
export default adapter;
|
||||
}
|
3364
node_modules/webrtc-adapter/out/adapter.js
generated
vendored
Normal file
3364
node_modules/webrtc-adapter/out/adapter.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3363
node_modules/webrtc-adapter/out/adapter_no_global.js
generated
vendored
Normal file
3363
node_modules/webrtc-adapter/out/adapter_no_global.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
35
node_modules/webrtc-adapter/out/esbuild.js
generated
vendored
Normal file
35
node_modules/webrtc-adapter/out/esbuild.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
62
node_modules/webrtc-adapter/package.json
generated
vendored
Normal file
62
node_modules/webrtc-adapter/package.json
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
{
|
||||
"name": "webrtc-adapter",
|
||||
"version": "8.2.3",
|
||||
"description": "A shim to insulate apps from WebRTC spec changes and browser prefix differences",
|
||||
"license": "BSD-3-Clause",
|
||||
"main": "./dist/adapter_core.js",
|
||||
"types": "./index.d.ts",
|
||||
"module": "./src/js/adapter_core.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webrtchacks/adapter.git"
|
||||
},
|
||||
"authors": [
|
||||
"The WebRTC project authors (https://www.webrtc.org/)",
|
||||
"The adapter.js project authors (https://github.com/webrtchacks/adapter/)"
|
||||
],
|
||||
"scripts": {
|
||||
"preversion": "git stash && npm install && npm update && BROWSER=chrome BVER=stable CI=true npm test && git checkout -B bumpVersion && grunt build && grunt copyForPublish && git add package.json release/* && git commit -m 'Add adapter artifacts' --allow-empty",
|
||||
"version": "",
|
||||
"postversion": "export GITTAG=\"echo $(git describe --abbrev=0 --tags | sed 's/^v//')\" && git push --force --set-upstream origin bumpVersion --follow-tags && git checkout gh-pages && git pull && cp out/adapter.js adapter.js && cp adapter.js adapter-`$GITTAG`.js && rm adapter-latest.js && ln -s adapter-`$GITTAG`.js adapter-latest.js && mkdir -p adapter-`$GITTAG`-variants && cp out/adapter.js adapter-`$GITTAG`-variants/ && cp out/adapter_*.js adapter-`$GITTAG`-variants/ && git add adapter.js adapter-latest.js adapter-`$GITTAG`.js adapter-`$GITTAG`-variants && git commit -m `$GITTAG` && git push --set-upstream origin gh-pages && git checkout main",
|
||||
"prepare": "grunt build",
|
||||
"prepublishonly": "npm test",
|
||||
"test": "grunt && mocha test/unit && grunt downloadBrowser && karma start test/karma.conf.js",
|
||||
"lint-and-unit-tests": "grunt && mocha test/unit",
|
||||
"e2e-tests": "grunt && grunt downloadBrowser && karma start test/karma.conf.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"sdp": "^3.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"npm": ">=3.10.0",
|
||||
"node": ">=6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.21.0",
|
||||
"@babel/preset-env": "^7.20.2",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"brfs": "^1.5.0",
|
||||
"chai": "^3.5.0",
|
||||
"grunt": "^1.1.0",
|
||||
"grunt-babel": "^8.0.0",
|
||||
"grunt-browserify": "^6.0.0",
|
||||
"grunt-cli": "^1.3.1",
|
||||
"grunt-contrib-clean": "^1.1.0",
|
||||
"grunt-contrib-copy": "^1.0.0",
|
||||
"grunt-eslint": "^24.0.0",
|
||||
"grunt-shell": "^2.1.0",
|
||||
"karma": "^6.4.1",
|
||||
"karma-browserify": "^8.1.0",
|
||||
"karma-chai": "^0.1.0",
|
||||
"karma-chrome-launcher": "^2.2.0",
|
||||
"karma-firefox-launcher": "^1.3.0",
|
||||
"karma-mocha": "^2.0.1",
|
||||
"karma-mocha-reporter": "^2.2.3",
|
||||
"karma-safari-launcher": "^1.0.0",
|
||||
"karma-stability-reporter": "^3.0.1",
|
||||
"mocha": "^10.1.0",
|
||||
"sinon": "^2.2.0",
|
||||
"sinon-chai": "^2.14.0",
|
||||
"travis-multirunner": "^5.0.1"
|
||||
}
|
||||
}
|
16
node_modules/webrtc-adapter/src/js/adapter_core.js
generated
vendored
Normal file
16
node_modules/webrtc-adapter/src/js/adapter_core.js
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
|
||||
'use strict';
|
||||
|
||||
import {adapterFactory} from './adapter_factory.js';
|
||||
|
||||
const adapter =
|
||||
adapterFactory({window: typeof window === 'undefined' ? undefined : window});
|
||||
export default adapter;
|
16
node_modules/webrtc-adapter/src/js/adapter_core5.js
generated
vendored
Normal file
16
node_modules/webrtc-adapter/src/js/adapter_core5.js
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
|
||||
'use strict';
|
||||
|
||||
import {adapterFactory} from './adapter_factory.js';
|
||||
|
||||
const adapter =
|
||||
adapterFactory({window: typeof window === 'undefined' ? undefined : window});
|
||||
module.exports = adapter; // this is the difference from adapter_core.
|
139
node_modules/webrtc-adapter/src/js/adapter_factory.js
generated
vendored
Normal file
139
node_modules/webrtc-adapter/src/js/adapter_factory.js
generated
vendored
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
import * as utils from './utils';
|
||||
|
||||
// Browser shims.
|
||||
import * as chromeShim from './chrome/chrome_shim';
|
||||
import * as firefoxShim from './firefox/firefox_shim';
|
||||
import * as safariShim from './safari/safari_shim';
|
||||
import * as commonShim from './common_shim';
|
||||
import * as sdp from 'sdp';
|
||||
|
||||
// Shimming starts here.
|
||||
export function adapterFactory({window} = {}, options = {
|
||||
shimChrome: true,
|
||||
shimFirefox: true,
|
||||
shimSafari: true,
|
||||
}) {
|
||||
// Utils.
|
||||
const logging = utils.log;
|
||||
const browserDetails = utils.detectBrowser(window);
|
||||
|
||||
const adapter = {
|
||||
browserDetails,
|
||||
commonShim,
|
||||
extractVersion: utils.extractVersion,
|
||||
disableLog: utils.disableLog,
|
||||
disableWarnings: utils.disableWarnings,
|
||||
// Expose sdp as a convenience. For production apps include directly.
|
||||
sdp,
|
||||
};
|
||||
|
||||
// Shim browser if found.
|
||||
switch (browserDetails.browser) {
|
||||
case 'chrome':
|
||||
if (!chromeShim || !chromeShim.shimPeerConnection ||
|
||||
!options.shimChrome) {
|
||||
logging('Chrome shim is not included in this adapter release.');
|
||||
return adapter;
|
||||
}
|
||||
if (browserDetails.version === null) {
|
||||
logging('Chrome shim can not determine version, not shimming.');
|
||||
return adapter;
|
||||
}
|
||||
logging('adapter.js shimming chrome.');
|
||||
// Export to the adapter global object visible in the browser.
|
||||
adapter.browserShim = chromeShim;
|
||||
|
||||
// Must be called before shimPeerConnection.
|
||||
commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails);
|
||||
commonShim.shimParameterlessSetLocalDescription(window, browserDetails);
|
||||
|
||||
chromeShim.shimGetUserMedia(window, browserDetails);
|
||||
chromeShim.shimMediaStream(window, browserDetails);
|
||||
chromeShim.shimPeerConnection(window, browserDetails);
|
||||
chromeShim.shimOnTrack(window, browserDetails);
|
||||
chromeShim.shimAddTrackRemoveTrack(window, browserDetails);
|
||||
chromeShim.shimGetSendersWithDtmf(window, browserDetails);
|
||||
chromeShim.shimGetStats(window, browserDetails);
|
||||
chromeShim.shimSenderReceiverGetStats(window, browserDetails);
|
||||
chromeShim.fixNegotiationNeeded(window, browserDetails);
|
||||
|
||||
commonShim.shimRTCIceCandidate(window, browserDetails);
|
||||
commonShim.shimRTCIceCandidateRelayProtocol(window, browserDetails);
|
||||
commonShim.shimConnectionState(window, browserDetails);
|
||||
commonShim.shimMaxMessageSize(window, browserDetails);
|
||||
commonShim.shimSendThrowTypeError(window, browserDetails);
|
||||
commonShim.removeExtmapAllowMixed(window, browserDetails);
|
||||
break;
|
||||
case 'firefox':
|
||||
if (!firefoxShim || !firefoxShim.shimPeerConnection ||
|
||||
!options.shimFirefox) {
|
||||
logging('Firefox shim is not included in this adapter release.');
|
||||
return adapter;
|
||||
}
|
||||
logging('adapter.js shimming firefox.');
|
||||
// Export to the adapter global object visible in the browser.
|
||||
adapter.browserShim = firefoxShim;
|
||||
|
||||
// Must be called before shimPeerConnection.
|
||||
commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails);
|
||||
commonShim.shimParameterlessSetLocalDescription(window, browserDetails);
|
||||
|
||||
firefoxShim.shimGetUserMedia(window, browserDetails);
|
||||
firefoxShim.shimPeerConnection(window, browserDetails);
|
||||
firefoxShim.shimOnTrack(window, browserDetails);
|
||||
firefoxShim.shimRemoveStream(window, browserDetails);
|
||||
firefoxShim.shimSenderGetStats(window, browserDetails);
|
||||
firefoxShim.shimReceiverGetStats(window, browserDetails);
|
||||
firefoxShim.shimRTCDataChannel(window, browserDetails);
|
||||
firefoxShim.shimAddTransceiver(window, browserDetails);
|
||||
firefoxShim.shimGetParameters(window, browserDetails);
|
||||
firefoxShim.shimCreateOffer(window, browserDetails);
|
||||
firefoxShim.shimCreateAnswer(window, browserDetails);
|
||||
|
||||
commonShim.shimRTCIceCandidate(window, browserDetails);
|
||||
commonShim.shimConnectionState(window, browserDetails);
|
||||
commonShim.shimMaxMessageSize(window, browserDetails);
|
||||
commonShim.shimSendThrowTypeError(window, browserDetails);
|
||||
break;
|
||||
case 'safari':
|
||||
if (!safariShim || !options.shimSafari) {
|
||||
logging('Safari shim is not included in this adapter release.');
|
||||
return adapter;
|
||||
}
|
||||
logging('adapter.js shimming safari.');
|
||||
// Export to the adapter global object visible in the browser.
|
||||
adapter.browserShim = safariShim;
|
||||
|
||||
// Must be called before shimCallbackAPI.
|
||||
commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails);
|
||||
commonShim.shimParameterlessSetLocalDescription(window, browserDetails);
|
||||
|
||||
safariShim.shimRTCIceServerUrls(window, browserDetails);
|
||||
safariShim.shimCreateOfferLegacy(window, browserDetails);
|
||||
safariShim.shimCallbacksAPI(window, browserDetails);
|
||||
safariShim.shimLocalStreamsAPI(window, browserDetails);
|
||||
safariShim.shimRemoteStreamsAPI(window, browserDetails);
|
||||
safariShim.shimTrackEventTransceiver(window, browserDetails);
|
||||
safariShim.shimGetUserMedia(window, browserDetails);
|
||||
safariShim.shimAudioContext(window, browserDetails);
|
||||
|
||||
commonShim.shimRTCIceCandidate(window, browserDetails);
|
||||
commonShim.shimRTCIceCandidateRelayProtocol(window, browserDetails);
|
||||
commonShim.shimMaxMessageSize(window, browserDetails);
|
||||
commonShim.shimSendThrowTypeError(window, browserDetails);
|
||||
commonShim.removeExtmapAllowMixed(window, browserDetails);
|
||||
break;
|
||||
default:
|
||||
logging('Unsupported browser!');
|
||||
break;
|
||||
}
|
||||
|
||||
return adapter;
|
||||
}
|
702
node_modules/webrtc-adapter/src/js/chrome/chrome_shim.js
generated
vendored
Normal file
702
node_modules/webrtc-adapter/src/js/chrome/chrome_shim.js
generated
vendored
Normal file
@ -0,0 +1,702 @@
|
||||
/*
|
||||
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
'use strict';
|
||||
import * as utils from '../utils.js';
|
||||
|
||||
export {shimGetUserMedia} from './getusermedia';
|
||||
export {shimGetDisplayMedia} from './getdisplaymedia';
|
||||
|
||||
export function shimMediaStream(window) {
|
||||
window.MediaStream = window.MediaStream || window.webkitMediaStream;
|
||||
}
|
||||
|
||||
export function shimOnTrack(window) {
|
||||
if (typeof window === 'object' && window.RTCPeerConnection && !('ontrack' in
|
||||
window.RTCPeerConnection.prototype)) {
|
||||
Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', {
|
||||
get() {
|
||||
return this._ontrack;
|
||||
},
|
||||
set(f) {
|
||||
if (this._ontrack) {
|
||||
this.removeEventListener('track', this._ontrack);
|
||||
}
|
||||
this.addEventListener('track', this._ontrack = f);
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
const origSetRemoteDescription =
|
||||
window.RTCPeerConnection.prototype.setRemoteDescription;
|
||||
window.RTCPeerConnection.prototype.setRemoteDescription =
|
||||
function setRemoteDescription() {
|
||||
if (!this._ontrackpoly) {
|
||||
this._ontrackpoly = (e) => {
|
||||
// onaddstream does not fire when a track is added to an existing
|
||||
// stream. But stream.onaddtrack is implemented so we use that.
|
||||
e.stream.addEventListener('addtrack', te => {
|
||||
let receiver;
|
||||
if (window.RTCPeerConnection.prototype.getReceivers) {
|
||||
receiver = this.getReceivers()
|
||||
.find(r => r.track && r.track.id === te.track.id);
|
||||
} else {
|
||||
receiver = {track: te.track};
|
||||
}
|
||||
|
||||
const event = new Event('track');
|
||||
event.track = te.track;
|
||||
event.receiver = receiver;
|
||||
event.transceiver = {receiver};
|
||||
event.streams = [e.stream];
|
||||
this.dispatchEvent(event);
|
||||
});
|
||||
e.stream.getTracks().forEach(track => {
|
||||
let receiver;
|
||||
if (window.RTCPeerConnection.prototype.getReceivers) {
|
||||
receiver = this.getReceivers()
|
||||
.find(r => r.track && r.track.id === track.id);
|
||||
} else {
|
||||
receiver = {track};
|
||||
}
|
||||
const event = new Event('track');
|
||||
event.track = track;
|
||||
event.receiver = receiver;
|
||||
event.transceiver = {receiver};
|
||||
event.streams = [e.stream];
|
||||
this.dispatchEvent(event);
|
||||
});
|
||||
};
|
||||
this.addEventListener('addstream', this._ontrackpoly);
|
||||
}
|
||||
return origSetRemoteDescription.apply(this, arguments);
|
||||
};
|
||||
} else {
|
||||
// even if RTCRtpTransceiver is in window, it is only used and
|
||||
// emitted in unified-plan. Unfortunately this means we need
|
||||
// to unconditionally wrap the event.
|
||||
utils.wrapPeerConnectionEvent(window, 'track', e => {
|
||||
if (!e.transceiver) {
|
||||
Object.defineProperty(e, 'transceiver',
|
||||
{value: {receiver: e.receiver}});
|
||||
}
|
||||
return e;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function shimGetSendersWithDtmf(window) {
|
||||
// Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack.
|
||||
if (typeof window === 'object' && window.RTCPeerConnection &&
|
||||
!('getSenders' in window.RTCPeerConnection.prototype) &&
|
||||
'createDTMFSender' in window.RTCPeerConnection.prototype) {
|
||||
const shimSenderWithDtmf = function(pc, track) {
|
||||
return {
|
||||
track,
|
||||
get dtmf() {
|
||||
if (this._dtmf === undefined) {
|
||||
if (track.kind === 'audio') {
|
||||
this._dtmf = pc.createDTMFSender(track);
|
||||
} else {
|
||||
this._dtmf = null;
|
||||
}
|
||||
}
|
||||
return this._dtmf;
|
||||
},
|
||||
_pc: pc
|
||||
};
|
||||
};
|
||||
|
||||
// augment addTrack when getSenders is not available.
|
||||
if (!window.RTCPeerConnection.prototype.getSenders) {
|
||||
window.RTCPeerConnection.prototype.getSenders = function getSenders() {
|
||||
this._senders = this._senders || [];
|
||||
return this._senders.slice(); // return a copy of the internal state.
|
||||
};
|
||||
const origAddTrack = window.RTCPeerConnection.prototype.addTrack;
|
||||
window.RTCPeerConnection.prototype.addTrack =
|
||||
function addTrack(track, stream) {
|
||||
let sender = origAddTrack.apply(this, arguments);
|
||||
if (!sender) {
|
||||
sender = shimSenderWithDtmf(this, track);
|
||||
this._senders.push(sender);
|
||||
}
|
||||
return sender;
|
||||
};
|
||||
|
||||
const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;
|
||||
window.RTCPeerConnection.prototype.removeTrack =
|
||||
function removeTrack(sender) {
|
||||
origRemoveTrack.apply(this, arguments);
|
||||
const idx = this._senders.indexOf(sender);
|
||||
if (idx !== -1) {
|
||||
this._senders.splice(idx, 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
const origAddStream = window.RTCPeerConnection.prototype.addStream;
|
||||
window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
|
||||
this._senders = this._senders || [];
|
||||
origAddStream.apply(this, [stream]);
|
||||
stream.getTracks().forEach(track => {
|
||||
this._senders.push(shimSenderWithDtmf(this, track));
|
||||
});
|
||||
};
|
||||
|
||||
const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
|
||||
window.RTCPeerConnection.prototype.removeStream =
|
||||
function removeStream(stream) {
|
||||
this._senders = this._senders || [];
|
||||
origRemoveStream.apply(this, [stream]);
|
||||
|
||||
stream.getTracks().forEach(track => {
|
||||
const sender = this._senders.find(s => s.track === track);
|
||||
if (sender) { // remove sender
|
||||
this._senders.splice(this._senders.indexOf(sender), 1);
|
||||
}
|
||||
});
|
||||
};
|
||||
} else if (typeof window === 'object' && window.RTCPeerConnection &&
|
||||
'getSenders' in window.RTCPeerConnection.prototype &&
|
||||
'createDTMFSender' in window.RTCPeerConnection.prototype &&
|
||||
window.RTCRtpSender &&
|
||||
!('dtmf' in window.RTCRtpSender.prototype)) {
|
||||
const origGetSenders = window.RTCPeerConnection.prototype.getSenders;
|
||||
window.RTCPeerConnection.prototype.getSenders = function getSenders() {
|
||||
const senders = origGetSenders.apply(this, []);
|
||||
senders.forEach(sender => sender._pc = this);
|
||||
return senders;
|
||||
};
|
||||
|
||||
Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', {
|
||||
get() {
|
||||
if (this._dtmf === undefined) {
|
||||
if (this.track.kind === 'audio') {
|
||||
this._dtmf = this._pc.createDTMFSender(this.track);
|
||||
} else {
|
||||
this._dtmf = null;
|
||||
}
|
||||
}
|
||||
return this._dtmf;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function shimGetStats(window) {
|
||||
if (!window.RTCPeerConnection) {
|
||||
return;
|
||||
}
|
||||
|
||||
const origGetStats = window.RTCPeerConnection.prototype.getStats;
|
||||
window.RTCPeerConnection.prototype.getStats = function getStats() {
|
||||
const [selector, onSucc, onErr] = arguments;
|
||||
|
||||
// If selector is a function then we are in the old style stats so just
|
||||
// pass back the original getStats format to avoid breaking old users.
|
||||
if (arguments.length > 0 && typeof selector === 'function') {
|
||||
return origGetStats.apply(this, arguments);
|
||||
}
|
||||
|
||||
// When spec-style getStats is supported, return those when called with
|
||||
// either no arguments or the selector argument is null.
|
||||
if (origGetStats.length === 0 && (arguments.length === 0 ||
|
||||
typeof selector !== 'function')) {
|
||||
return origGetStats.apply(this, []);
|
||||
}
|
||||
|
||||
const fixChromeStats_ = function(response) {
|
||||
const standardReport = {};
|
||||
const reports = response.result();
|
||||
reports.forEach(report => {
|
||||
const standardStats = {
|
||||
id: report.id,
|
||||
timestamp: report.timestamp,
|
||||
type: {
|
||||
localcandidate: 'local-candidate',
|
||||
remotecandidate: 'remote-candidate'
|
||||
}[report.type] || report.type
|
||||
};
|
||||
report.names().forEach(name => {
|
||||
standardStats[name] = report.stat(name);
|
||||
});
|
||||
standardReport[standardStats.id] = standardStats;
|
||||
});
|
||||
|
||||
return standardReport;
|
||||
};
|
||||
|
||||
// shim getStats with maplike support
|
||||
const makeMapStats = function(stats) {
|
||||
return new Map(Object.keys(stats).map(key => [key, stats[key]]));
|
||||
};
|
||||
|
||||
if (arguments.length >= 2) {
|
||||
const successCallbackWrapper_ = function(response) {
|
||||
onSucc(makeMapStats(fixChromeStats_(response)));
|
||||
};
|
||||
|
||||
return origGetStats.apply(this, [successCallbackWrapper_,
|
||||
selector]);
|
||||
}
|
||||
|
||||
// promise-support
|
||||
return new Promise((resolve, reject) => {
|
||||
origGetStats.apply(this, [
|
||||
function(response) {
|
||||
resolve(makeMapStats(fixChromeStats_(response)));
|
||||
}, reject]);
|
||||
}).then(onSucc, onErr);
|
||||
};
|
||||
}
|
||||
|
||||
export function shimSenderReceiverGetStats(window) {
|
||||
if (!(typeof window === 'object' && window.RTCPeerConnection &&
|
||||
window.RTCRtpSender && window.RTCRtpReceiver)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// shim sender stats.
|
||||
if (!('getStats' in window.RTCRtpSender.prototype)) {
|
||||
const origGetSenders = window.RTCPeerConnection.prototype.getSenders;
|
||||
if (origGetSenders) {
|
||||
window.RTCPeerConnection.prototype.getSenders = function getSenders() {
|
||||
const senders = origGetSenders.apply(this, []);
|
||||
senders.forEach(sender => sender._pc = this);
|
||||
return senders;
|
||||
};
|
||||
}
|
||||
|
||||
const origAddTrack = window.RTCPeerConnection.prototype.addTrack;
|
||||
if (origAddTrack) {
|
||||
window.RTCPeerConnection.prototype.addTrack = function addTrack() {
|
||||
const sender = origAddTrack.apply(this, arguments);
|
||||
sender._pc = this;
|
||||
return sender;
|
||||
};
|
||||
}
|
||||
window.RTCRtpSender.prototype.getStats = function getStats() {
|
||||
const sender = this;
|
||||
return this._pc.getStats().then(result =>
|
||||
/* Note: this will include stats of all senders that
|
||||
* send a track with the same id as sender.track as
|
||||
* it is not possible to identify the RTCRtpSender.
|
||||
*/
|
||||
utils.filterStats(result, sender.track, true));
|
||||
};
|
||||
}
|
||||
|
||||
// shim receiver stats.
|
||||
if (!('getStats' in window.RTCRtpReceiver.prototype)) {
|
||||
const origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;
|
||||
if (origGetReceivers) {
|
||||
window.RTCPeerConnection.prototype.getReceivers =
|
||||
function getReceivers() {
|
||||
const receivers = origGetReceivers.apply(this, []);
|
||||
receivers.forEach(receiver => receiver._pc = this);
|
||||
return receivers;
|
||||
};
|
||||
}
|
||||
utils.wrapPeerConnectionEvent(window, 'track', e => {
|
||||
e.receiver._pc = e.srcElement;
|
||||
return e;
|
||||
});
|
||||
window.RTCRtpReceiver.prototype.getStats = function getStats() {
|
||||
const receiver = this;
|
||||
return this._pc.getStats().then(result =>
|
||||
utils.filterStats(result, receiver.track, false));
|
||||
};
|
||||
}
|
||||
|
||||
if (!('getStats' in window.RTCRtpSender.prototype &&
|
||||
'getStats' in window.RTCRtpReceiver.prototype)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// shim RTCPeerConnection.getStats(track).
|
||||
const origGetStats = window.RTCPeerConnection.prototype.getStats;
|
||||
window.RTCPeerConnection.prototype.getStats = function getStats() {
|
||||
if (arguments.length > 0 &&
|
||||
arguments[0] instanceof window.MediaStreamTrack) {
|
||||
const track = arguments[0];
|
||||
let sender;
|
||||
let receiver;
|
||||
let err;
|
||||
this.getSenders().forEach(s => {
|
||||
if (s.track === track) {
|
||||
if (sender) {
|
||||
err = true;
|
||||
} else {
|
||||
sender = s;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.getReceivers().forEach(r => {
|
||||
if (r.track === track) {
|
||||
if (receiver) {
|
||||
err = true;
|
||||
} else {
|
||||
receiver = r;
|
||||
}
|
||||
}
|
||||
return r.track === track;
|
||||
});
|
||||
if (err || (sender && receiver)) {
|
||||
return Promise.reject(new DOMException(
|
||||
'There are more than one sender or receiver for the track.',
|
||||
'InvalidAccessError'));
|
||||
} else if (sender) {
|
||||
return sender.getStats();
|
||||
} else if (receiver) {
|
||||
return receiver.getStats();
|
||||
}
|
||||
return Promise.reject(new DOMException(
|
||||
'There is no sender or receiver for the track.',
|
||||
'InvalidAccessError'));
|
||||
}
|
||||
return origGetStats.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
export function shimAddTrackRemoveTrackWithNative(window) {
|
||||
// shim addTrack/removeTrack with native variants in order to make
|
||||
// the interactions with legacy getLocalStreams behave as in other browsers.
|
||||
// Keeps a mapping stream.id => [stream, rtpsenders...]
|
||||
window.RTCPeerConnection.prototype.getLocalStreams =
|
||||
function getLocalStreams() {
|
||||
this._shimmedLocalStreams = this._shimmedLocalStreams || {};
|
||||
return Object.keys(this._shimmedLocalStreams)
|
||||
.map(streamId => this._shimmedLocalStreams[streamId][0]);
|
||||
};
|
||||
|
||||
const origAddTrack = window.RTCPeerConnection.prototype.addTrack;
|
||||
window.RTCPeerConnection.prototype.addTrack =
|
||||
function addTrack(track, stream) {
|
||||
if (!stream) {
|
||||
return origAddTrack.apply(this, arguments);
|
||||
}
|
||||
this._shimmedLocalStreams = this._shimmedLocalStreams || {};
|
||||
|
||||
const sender = origAddTrack.apply(this, arguments);
|
||||
if (!this._shimmedLocalStreams[stream.id]) {
|
||||
this._shimmedLocalStreams[stream.id] = [stream, sender];
|
||||
} else if (this._shimmedLocalStreams[stream.id].indexOf(sender) === -1) {
|
||||
this._shimmedLocalStreams[stream.id].push(sender);
|
||||
}
|
||||
return sender;
|
||||
};
|
||||
|
||||
const origAddStream = window.RTCPeerConnection.prototype.addStream;
|
||||
window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
|
||||
this._shimmedLocalStreams = this._shimmedLocalStreams || {};
|
||||
|
||||
stream.getTracks().forEach(track => {
|
||||
const alreadyExists = this.getSenders().find(s => s.track === track);
|
||||
if (alreadyExists) {
|
||||
throw new DOMException('Track already exists.',
|
||||
'InvalidAccessError');
|
||||
}
|
||||
});
|
||||
const existingSenders = this.getSenders();
|
||||
origAddStream.apply(this, arguments);
|
||||
const newSenders = this.getSenders()
|
||||
.filter(newSender => existingSenders.indexOf(newSender) === -1);
|
||||
this._shimmedLocalStreams[stream.id] = [stream].concat(newSenders);
|
||||
};
|
||||
|
||||
const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
|
||||
window.RTCPeerConnection.prototype.removeStream =
|
||||
function removeStream(stream) {
|
||||
this._shimmedLocalStreams = this._shimmedLocalStreams || {};
|
||||
delete this._shimmedLocalStreams[stream.id];
|
||||
return origRemoveStream.apply(this, arguments);
|
||||
};
|
||||
|
||||
const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;
|
||||
window.RTCPeerConnection.prototype.removeTrack =
|
||||
function removeTrack(sender) {
|
||||
this._shimmedLocalStreams = this._shimmedLocalStreams || {};
|
||||
if (sender) {
|
||||
Object.keys(this._shimmedLocalStreams).forEach(streamId => {
|
||||
const idx = this._shimmedLocalStreams[streamId].indexOf(sender);
|
||||
if (idx !== -1) {
|
||||
this._shimmedLocalStreams[streamId].splice(idx, 1);
|
||||
}
|
||||
if (this._shimmedLocalStreams[streamId].length === 1) {
|
||||
delete this._shimmedLocalStreams[streamId];
|
||||
}
|
||||
});
|
||||
}
|
||||
return origRemoveTrack.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
export function shimAddTrackRemoveTrack(window, browserDetails) {
|
||||
if (!window.RTCPeerConnection) {
|
||||
return;
|
||||
}
|
||||
// shim addTrack and removeTrack.
|
||||
if (window.RTCPeerConnection.prototype.addTrack &&
|
||||
browserDetails.version >= 65) {
|
||||
return shimAddTrackRemoveTrackWithNative(window);
|
||||
}
|
||||
|
||||
// also shim pc.getLocalStreams when addTrack is shimmed
|
||||
// to return the original streams.
|
||||
const origGetLocalStreams = window.RTCPeerConnection.prototype
|
||||
.getLocalStreams;
|
||||
window.RTCPeerConnection.prototype.getLocalStreams =
|
||||
function getLocalStreams() {
|
||||
const nativeStreams = origGetLocalStreams.apply(this);
|
||||
this._reverseStreams = this._reverseStreams || {};
|
||||
return nativeStreams.map(stream => this._reverseStreams[stream.id]);
|
||||
};
|
||||
|
||||
const origAddStream = window.RTCPeerConnection.prototype.addStream;
|
||||
window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
|
||||
this._streams = this._streams || {};
|
||||
this._reverseStreams = this._reverseStreams || {};
|
||||
|
||||
stream.getTracks().forEach(track => {
|
||||
const alreadyExists = this.getSenders().find(s => s.track === track);
|
||||
if (alreadyExists) {
|
||||
throw new DOMException('Track already exists.',
|
||||
'InvalidAccessError');
|
||||
}
|
||||
});
|
||||
// Add identity mapping for consistency with addTrack.
|
||||
// Unless this is being used with a stream from addTrack.
|
||||
if (!this._reverseStreams[stream.id]) {
|
||||
const newStream = new window.MediaStream(stream.getTracks());
|
||||
this._streams[stream.id] = newStream;
|
||||
this._reverseStreams[newStream.id] = stream;
|
||||
stream = newStream;
|
||||
}
|
||||
origAddStream.apply(this, [stream]);
|
||||
};
|
||||
|
||||
const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
|
||||
window.RTCPeerConnection.prototype.removeStream =
|
||||
function removeStream(stream) {
|
||||
this._streams = this._streams || {};
|
||||
this._reverseStreams = this._reverseStreams || {};
|
||||
|
||||
origRemoveStream.apply(this, [(this._streams[stream.id] || stream)]);
|
||||
delete this._reverseStreams[(this._streams[stream.id] ?
|
||||
this._streams[stream.id].id : stream.id)];
|
||||
delete this._streams[stream.id];
|
||||
};
|
||||
|
||||
window.RTCPeerConnection.prototype.addTrack =
|
||||
function addTrack(track, stream) {
|
||||
if (this.signalingState === 'closed') {
|
||||
throw new DOMException(
|
||||
'The RTCPeerConnection\'s signalingState is \'closed\'.',
|
||||
'InvalidStateError');
|
||||
}
|
||||
const streams = [].slice.call(arguments, 1);
|
||||
if (streams.length !== 1 ||
|
||||
!streams[0].getTracks().find(t => t === track)) {
|
||||
// this is not fully correct but all we can manage without
|
||||
// [[associated MediaStreams]] internal slot.
|
||||
throw new DOMException(
|
||||
'The adapter.js addTrack polyfill only supports a single ' +
|
||||
' stream which is associated with the specified track.',
|
||||
'NotSupportedError');
|
||||
}
|
||||
|
||||
const alreadyExists = this.getSenders().find(s => s.track === track);
|
||||
if (alreadyExists) {
|
||||
throw new DOMException('Track already exists.',
|
||||
'InvalidAccessError');
|
||||
}
|
||||
|
||||
this._streams = this._streams || {};
|
||||
this._reverseStreams = this._reverseStreams || {};
|
||||
const oldStream = this._streams[stream.id];
|
||||
if (oldStream) {
|
||||
// this is using odd Chrome behaviour, use with caution:
|
||||
// https://bugs.chromium.org/p/webrtc/issues/detail?id=7815
|
||||
// Note: we rely on the high-level addTrack/dtmf shim to
|
||||
// create the sender with a dtmf sender.
|
||||
oldStream.addTrack(track);
|
||||
|
||||
// Trigger ONN async.
|
||||
Promise.resolve().then(() => {
|
||||
this.dispatchEvent(new Event('negotiationneeded'));
|
||||
});
|
||||
} else {
|
||||
const newStream = new window.MediaStream([track]);
|
||||
this._streams[stream.id] = newStream;
|
||||
this._reverseStreams[newStream.id] = stream;
|
||||
this.addStream(newStream);
|
||||
}
|
||||
return this.getSenders().find(s => s.track === track);
|
||||
};
|
||||
|
||||
// replace the internal stream id with the external one and
|
||||
// vice versa.
|
||||
function replaceInternalStreamId(pc, description) {
|
||||
let sdp = description.sdp;
|
||||
Object.keys(pc._reverseStreams || []).forEach(internalId => {
|
||||
const externalStream = pc._reverseStreams[internalId];
|
||||
const internalStream = pc._streams[externalStream.id];
|
||||
sdp = sdp.replace(new RegExp(internalStream.id, 'g'),
|
||||
externalStream.id);
|
||||
});
|
||||
return new RTCSessionDescription({
|
||||
type: description.type,
|
||||
sdp
|
||||
});
|
||||
}
|
||||
function replaceExternalStreamId(pc, description) {
|
||||
let sdp = description.sdp;
|
||||
Object.keys(pc._reverseStreams || []).forEach(internalId => {
|
||||
const externalStream = pc._reverseStreams[internalId];
|
||||
const internalStream = pc._streams[externalStream.id];
|
||||
sdp = sdp.replace(new RegExp(externalStream.id, 'g'),
|
||||
internalStream.id);
|
||||
});
|
||||
return new RTCSessionDescription({
|
||||
type: description.type,
|
||||
sdp
|
||||
});
|
||||
}
|
||||
['createOffer', 'createAnswer'].forEach(function(method) {
|
||||
const nativeMethod = window.RTCPeerConnection.prototype[method];
|
||||
const methodObj = {[method]() {
|
||||
const args = arguments;
|
||||
const isLegacyCall = arguments.length &&
|
||||
typeof arguments[0] === 'function';
|
||||
if (isLegacyCall) {
|
||||
return nativeMethod.apply(this, [
|
||||
(description) => {
|
||||
const desc = replaceInternalStreamId(this, description);
|
||||
args[0].apply(null, [desc]);
|
||||
},
|
||||
(err) => {
|
||||
if (args[1]) {
|
||||
args[1].apply(null, err);
|
||||
}
|
||||
}, arguments[2]
|
||||
]);
|
||||
}
|
||||
return nativeMethod.apply(this, arguments)
|
||||
.then(description => replaceInternalStreamId(this, description));
|
||||
}};
|
||||
window.RTCPeerConnection.prototype[method] = methodObj[method];
|
||||
});
|
||||
|
||||
const origSetLocalDescription =
|
||||
window.RTCPeerConnection.prototype.setLocalDescription;
|
||||
window.RTCPeerConnection.prototype.setLocalDescription =
|
||||
function setLocalDescription() {
|
||||
if (!arguments.length || !arguments[0].type) {
|
||||
return origSetLocalDescription.apply(this, arguments);
|
||||
}
|
||||
arguments[0] = replaceExternalStreamId(this, arguments[0]);
|
||||
return origSetLocalDescription.apply(this, arguments);
|
||||
};
|
||||
|
||||
// TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier
|
||||
|
||||
const origLocalDescription = Object.getOwnPropertyDescriptor(
|
||||
window.RTCPeerConnection.prototype, 'localDescription');
|
||||
Object.defineProperty(window.RTCPeerConnection.prototype,
|
||||
'localDescription', {
|
||||
get() {
|
||||
const description = origLocalDescription.get.apply(this);
|
||||
if (description.type === '') {
|
||||
return description;
|
||||
}
|
||||
return replaceInternalStreamId(this, description);
|
||||
}
|
||||
});
|
||||
|
||||
window.RTCPeerConnection.prototype.removeTrack =
|
||||
function removeTrack(sender) {
|
||||
if (this.signalingState === 'closed') {
|
||||
throw new DOMException(
|
||||
'The RTCPeerConnection\'s signalingState is \'closed\'.',
|
||||
'InvalidStateError');
|
||||
}
|
||||
// We can not yet check for sender instanceof RTCRtpSender
|
||||
// since we shim RTPSender. So we check if sender._pc is set.
|
||||
if (!sender._pc) {
|
||||
throw new DOMException('Argument 1 of RTCPeerConnection.removeTrack ' +
|
||||
'does not implement interface RTCRtpSender.', 'TypeError');
|
||||
}
|
||||
const isLocal = sender._pc === this;
|
||||
if (!isLocal) {
|
||||
throw new DOMException('Sender was not created by this connection.',
|
||||
'InvalidAccessError');
|
||||
}
|
||||
|
||||
// Search for the native stream the senders track belongs to.
|
||||
this._streams = this._streams || {};
|
||||
let stream;
|
||||
Object.keys(this._streams).forEach(streamid => {
|
||||
const hasTrack = this._streams[streamid].getTracks()
|
||||
.find(track => sender.track === track);
|
||||
if (hasTrack) {
|
||||
stream = this._streams[streamid];
|
||||
}
|
||||
});
|
||||
|
||||
if (stream) {
|
||||
if (stream.getTracks().length === 1) {
|
||||
// if this is the last track of the stream, remove the stream. This
|
||||
// takes care of any shimmed _senders.
|
||||
this.removeStream(this._reverseStreams[stream.id]);
|
||||
} else {
|
||||
// relying on the same odd chrome behaviour as above.
|
||||
stream.removeTrack(sender.track);
|
||||
}
|
||||
this.dispatchEvent(new Event('negotiationneeded'));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function shimPeerConnection(window, browserDetails) {
|
||||
if (!window.RTCPeerConnection && window.webkitRTCPeerConnection) {
|
||||
// very basic support for old versions.
|
||||
window.RTCPeerConnection = window.webkitRTCPeerConnection;
|
||||
}
|
||||
if (!window.RTCPeerConnection) {
|
||||
return;
|
||||
}
|
||||
|
||||
// shim implicit creation of RTCSessionDescription/RTCIceCandidate
|
||||
if (browserDetails.version < 53) {
|
||||
['setLocalDescription', 'setRemoteDescription', 'addIceCandidate']
|
||||
.forEach(function(method) {
|
||||
const nativeMethod = window.RTCPeerConnection.prototype[method];
|
||||
const methodObj = {[method]() {
|
||||
arguments[0] = new ((method === 'addIceCandidate') ?
|
||||
window.RTCIceCandidate :
|
||||
window.RTCSessionDescription)(arguments[0]);
|
||||
return nativeMethod.apply(this, arguments);
|
||||
}};
|
||||
window.RTCPeerConnection.prototype[method] = methodObj[method];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to fix ONN in plan-b mode.
|
||||
export function fixNegotiationNeeded(window, browserDetails) {
|
||||
utils.wrapPeerConnectionEvent(window, 'negotiationneeded', e => {
|
||||
const pc = e.target;
|
||||
if (browserDetails.version < 72 || (pc.getConfiguration &&
|
||||
pc.getConfiguration().sdpSemantics === 'plan-b')) {
|
||||
if (pc.signalingState !== 'stable') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
});
|
||||
}
|
50
node_modules/webrtc-adapter/src/js/chrome/getdisplaymedia.js
generated
vendored
Normal file
50
node_modules/webrtc-adapter/src/js/chrome/getdisplaymedia.js
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree.
|
||||
*/
|
||||
/* eslint-env node */
|
||||
'use strict';
|
||||
export function shimGetDisplayMedia(window, getSourceId) {
|
||||
if (window.navigator.mediaDevices &&
|
||||
'getDisplayMedia' in window.navigator.mediaDevices) {
|
||||
return;
|
||||
}
|
||||
if (!(window.navigator.mediaDevices)) {
|
||||
return;
|
||||
}
|
||||
// getSourceId is a function that returns a promise resolving with
|
||||
// the sourceId of the screen/window/tab to be shared.
|
||||
if (typeof getSourceId !== 'function') {
|
||||
console.error('shimGetDisplayMedia: getSourceId argument is not ' +
|
||||
'a function');
|
||||
return;
|
||||
}
|
||||
window.navigator.mediaDevices.getDisplayMedia =
|
||||
function getDisplayMedia(constraints) {
|
||||
return getSourceId(constraints)
|
||||
.then(sourceId => {
|
||||
const widthSpecified = constraints.video && constraints.video.width;
|
||||
const heightSpecified = constraints.video &&
|
||||
constraints.video.height;
|
||||
const frameRateSpecified = constraints.video &&
|
||||
constraints.video.frameRate;
|
||||
constraints.video = {
|
||||
mandatory: {
|
||||
chromeMediaSource: 'desktop',
|
||||
chromeMediaSourceId: sourceId,
|
||||
maxFrameRate: frameRateSpecified || 3
|
||||
}
|
||||
};
|
||||
if (widthSpecified) {
|
||||
constraints.video.mandatory.maxWidth = widthSpecified;
|
||||
}
|
||||
if (heightSpecified) {
|
||||
constraints.video.mandatory.maxHeight = heightSpecified;
|
||||
}
|
||||
return window.navigator.mediaDevices.getUserMedia(constraints);
|
||||
});
|
||||
};
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user