新增页面

This commit is contained in:
ljx120 2024-12-21 18:03:43 +08:00
parent 95bbabf00a
commit 2919bdfc90
188 changed files with 36513 additions and 107 deletions

9
.hbuilderx/launch.json Normal file
View File

@ -0,0 +1,9 @@
{
"version" : "1.0",
"configurations" : [
{
"playground" : "standard",
"type" : "uni-app:app-ios"
}
]
}

435
common/Order/OrderAll.vue Normal file
View 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>

View 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]}} &nbsp; &nbsp;{{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
View 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>

View 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>

View 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
View 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
View 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
View 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
View 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
View File

@ -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
View 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
View 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
View 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
View 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
}

View 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
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,263 @@
# barcode-detector
[![npm](https://img.shields.io/npm/v/barcode-detector)](https://www.npmjs.com/package/barcode-detector/v/latest) [![npm bundle size (scoped)](https://img.shields.io/bundlephobia/minzip/barcode-detector)](https://www.npmjs.com/package/barcode-detector/v/latest) [![jsDelivr hits (npm scoped)](https://img.shields.io/jsdelivr/npm/hm/barcode-detector?color=%23ff5627)](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).

View 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
View 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
View 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
View File

@ -0,0 +1,3 @@
{
"type": "commonjs"
}

1
node_modules/barcode-detector/dist/cjs/pure.d.ts generated vendored Normal file
View File

@ -0,0 +1 @@
export * from "./BarcodeDetector.js";

3
node_modules/barcode-detector/dist/cjs/pure.js generated vendored Normal file

File diff suppressed because one or more lines are too long

View 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;
}

View 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
View 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;

View 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
View 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
View 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
View File

@ -0,0 +1 @@
export * from "./BarcodeDetector.js";

2252
node_modules/barcode-detector/dist/es/pure.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View 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;
}

View 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
View 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

File diff suppressed because one or more lines are too long

3
node_modules/barcode-detector/dist/iife/pure.js generated vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

102
node_modules/barcode-detector/package.json generated vendored Normal file
View 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
View 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
View 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

File diff suppressed because one or more lines are too long

View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

773
node_modules/sdp/dist/sdp.js generated vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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).

View 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;

View 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;
};
};

View 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
View 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 };

View 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
View 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
View 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
View 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 {};

View 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
View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

77
node_modules/vue-qrcode-reader/package.json generated vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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;
});
}

View 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
View 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));
});
});
};
}
}

View 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
View 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]);
});
};
}

View 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);
};
}

View 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);
};
}

View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

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

File diff suppressed because one or more lines are too long

62
node_modules/webrtc-adapter/package.json generated vendored Normal file
View 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
View 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
View 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
View 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;
}

View 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;
});
}

View 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