Browse Source

采用pion webrtc v3.0

v4
dexter 4 years ago
parent
commit
58dce7a811
  1. 15
      go.mod
  2. 193
      go.sum
  3. 226
      main.go
  4. 19
      ui/dist/demo.html
  5. 584
      ui/dist/plugin-webrtc.common.js
  6. 1
      ui/dist/plugin-webrtc.common.js.map
  7. 1
      ui/dist/plugin-webrtc.css
  8. 594
      ui/dist/plugin-webrtc.umd.js
  9. 1
      ui/dist/plugin-webrtc.umd.js.map
  10. 2
      ui/dist/plugin-webrtc.umd.min.js
  11. 1
      ui/dist/plugin-webrtc.umd.min.js.map
  12. 9392
      ui/package-lock.json
  13. 15
      ui/package.json
  14. 124
      ui/src/App.vue
  15. 86
      ui/src/components/Player.vue

15
go.mod

@ -1,11 +1,16 @@
module github.com/Monibuca/plugin-webrtc
module github.com/Monibuca/plugin-webrtc/v3
go 1.13
require (
github.com/Monibuca/engine/v2 v2.2.5
github.com/Monibuca/plugin-gb28181 v1.0.5 // indirect
github.com/Monibuca/engine/v3 v3.0.0
github.com/Monibuca/plugin-rtp v1.0.0
github.com/pion/rtcp v1.2.1
github.com/pion/webrtc/v2 v2.2.14
github.com/Monibuca/utils/v3 v3.0.0-alpha2
github.com/pion/rtcp v1.2.6
github.com/pion/webrtc/v3 v3.0.4
github.com/shirou/gopsutil v2.20.8+incompatible // indirect
)
replace github.com/Monibuca/engine/v3 v3.0.0 => ../engine
replace github.com/Monibuca/utils/v3 => ../utils

193
go.sum

@ -1,66 +1,39 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Monibuca/engine/v2 v2.0.0/go.mod h1:34EYjjV15G6myuHOKaJkO7y5tJ1Arq/NfC9Weacr2mc=
github.com/Monibuca/engine/v2 v2.1.0 h1:pHeDCEFDusKFsZLpconYj8U5LCaWApnjd+yQRHYgQsQ=
github.com/Monibuca/engine/v2 v2.1.0/go.mod h1:34EYjjV15G6myuHOKaJkO7y5tJ1Arq/NfC9Weacr2mc=
github.com/Monibuca/engine/v2 v2.1.7 h1:/2k2Uupufizo0jiIkdYJsdHIf6VNvpLIxVVeIGGQgD4=
github.com/Monibuca/engine/v2 v2.1.7/go.mod h1:34EYjjV15G6myuHOKaJkO7y5tJ1Arq/NfC9Weacr2mc=
github.com/Monibuca/engine/v2 v2.1.9/go.mod h1:34EYjjV15G6myuHOKaJkO7y5tJ1Arq/NfC9Weacr2mc=
github.com/Monibuca/engine/v2 v2.2.0 h1:A4SyWwzVLegd8Oa6LfSW3LpNfBmWq+MHJJLO55gvaYI=
github.com/Monibuca/engine/v2 v2.2.0/go.mod h1:34EYjjV15G6myuHOKaJkO7y5tJ1Arq/NfC9Weacr2mc=
github.com/Monibuca/engine/v2 v2.2.2/go.mod h1:34EYjjV15G6myuHOKaJkO7y5tJ1Arq/NfC9Weacr2mc=
github.com/Monibuca/engine/v2 v2.2.5 h1:/w0BrvdTy4cqLD2uaIRaqBwdnu+/VDk+r3sjFbpbc1E=
github.com/Monibuca/engine/v2 v2.2.5/go.mod h1:34EYjjV15G6myuHOKaJkO7y5tJ1Arq/NfC9Weacr2mc=
github.com/Monibuca/plugin-gateway v1.2.6 h1:ZHwHMmjBs3Itxxd/Z/OR7c5QdED1sqSmBJ/6U+Y/Hc0=
github.com/Monibuca/plugin-gateway v1.2.6/go.mod h1:l+BaE5QZY0Pr92iiIXS67gt2VxcBuOxYyqIGOEGbuFk=
github.com/Monibuca/plugin-gb28181 v1.0.5 h1:zwRhAru6aIoi9kAm1Cf6gLTp5DU8dP5qTenBXgcGOfs=
github.com/Monibuca/plugin-gb28181 v1.0.5/go.mod h1:uhP+OZE78hX0IG3f4twEUKSF3B1QJhiyjblwExSRbBw=
github.com/Monibuca/plugin-hdl v1.2.5 h1:zIo4ptkIzn/L1KhutsZ2Bk17OoyRbundXG+8c1ki6cQ=
github.com/Monibuca/plugin-hdl v1.2.5/go.mod h1:+Qm9B5tQfxQdZ1hJQZbW4BZLOQWbPwN9qkB0vPGFo1U=
github.com/Monibuca/plugin-hls v1.2.1 h1:vD8LFB1t87fKuEycuQYa1nayCcEkRpIo0xosDJX3yGM=
github.com/Monibuca/plugin-hls v1.2.1/go.mod h1:8mIEvD09qDxp2Lso7fOQnfNFcxPcMxa6P9dGBbUOZD0=
github.com/Monibuca/plugin-jessica v1.3.0 h1:VPLPl76ykEHvrtQMy4+UZQBJd2gjYfWQbrg47qnOIT0=
github.com/Monibuca/plugin-jessica v1.3.0/go.mod h1:9TOsOzeVNbTCbgZ6xMANNMA0h5O/GxdlCLhavo6yVHM=
github.com/Monibuca/plugin-logrotate v1.2.3 h1:Q3V4VrN8fVUQnN+RIP+wn/+ZrZ/cu8xM5rTeIg74QVM=
github.com/Monibuca/plugin-logrotate v1.2.3/go.mod h1:bo2zR3H2CuyN2+dbsnZ6IvM+NT87r9H2RptVyyxkvTY=
github.com/Monibuca/plugin-record v1.0.4 h1:dPXJKlkljyhNUrpVP3586QO1L2DFvvl8m+ZXmQlEul8=
github.com/Monibuca/plugin-record v1.0.4/go.mod h1:POh+M09c+U1YAt6ratoKXahjt8GopEL0k6M8DUXbmAc=
github.com/Monibuca/plugin-rtmp v1.2.5 h1:y9tQ7ayg8y3PE8jpBmb3/EHNgBL5cppptKvulFdvkzE=
github.com/Monibuca/plugin-rtmp v1.2.5/go.mod h1:RSbufAndiyYfeLz4OiZwcGS/UTHCyTDtqvHzvzRQtWE=
github.com/Monibuca/plugin-rtp v0.0.0-20200531020026-1b12ef72f221 h1:WBC0eLB7J3PXWZiu4cr9kdcNAkR/74jf0+7zkYDzwZQ=
github.com/Monibuca/plugin-rtp v0.0.0-20200531020026-1b12ef72f221/go.mod h1:62NoacApn7++z5wQnr9ktSfn+vVZL0eSvbD/EqoSHoM=
github.com/Monibuca/plugin-rtp v1.0.0 h1:yksNsIIGxoKX8UZirkAUK+mGZ/XoEeS2vqbIqtqXyCg=
github.com/Monibuca/plugin-rtp v1.0.0/go.mod h1:0xkNm23a/BjVnEMz1zXyOqfEjoVmGe3PJqPNF1KyFGc=
github.com/Monibuca/plugin-rtsp v1.3.1 h1:b7xtRIBVcoa6WDseErVDzt+8dZGaUwhDLHxGuutROag=
github.com/Monibuca/plugin-rtsp v1.3.1/go.mod h1:N5nEu2SZTf4NMJn7DLlw39wQ4kXZAuMrfbbNtYES894=
github.com/Monibuca/plugin-ts v1.2.1 h1:Y2QgEal9/ot43QEvtzRkmA8yk+N2uzieAzKuujZJFMs=
github.com/Monibuca/plugin-ts v1.2.1/go.mod h1:MZsdv34Od1Kh1WOkuqIAO/t2irjzW39RMO9WbpFks4g=
github.com/Monibuca/plugin-webrtc v1.2.2/go.mod h1:ZPcGimoI8Yl/IzQJhSp4jgVOpmMeqPDcN7H8xv1Xj9g=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/funny/slab v0.0.0-20180511031532-b1fad5e5d478 h1:Db9StoJ6RZN3YttC0Pm0I4Y5izITRYch3RMbT59BYN0=
github.com/funny/slab v0.0.0-20180511031532-b1fad5e5d478/go.mod h1:0j1+svBH8ABEIPdUP0AIg4qedsybnXGJBakCEw8cfoo=
github.com/funny/utest v0.0.0-20161029064919-43870a374500 h1:Z0r1CZnoIWFB/Uiwh1BU5FYmuFe6L5NPi6XWQEmsTRg=
github.com/funny/utest v0.0.0-20161029064919-43870a374500/go.mod h1:mUn39tBov9jKnTWV1RlOYoNzxdBFHiSzXWdY1FoNGGg=
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
@ -72,133 +45,135 @@ github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRn
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/lucas-clemente/quic-go v0.7.1-0.20190401152353-907071221cf9 h1:tbuodUh2vuhOVZAdW3NEUvosFHUMJwUNl7jk/VSEiwc=
github.com/lucas-clemente/quic-go v0.7.1-0.20190401152353-907071221cf9/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw=
github.com/marten-seemann/qtls v0.2.3 h1:0yWJ43C62LsZt08vuQJDK1uC1czUc3FJeCLPoNAI4vA=
github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
github.com/mask-pp/rtp-ps v1.0.0 h1:JFxuJL9N+gD1ldgJlAy3b7rYfY8wAVHi9ODNmdP4+EE=
github.com/mask-pp/rtp-ps v1.0.0/go.mod h1:jCxsZ2G7z/jX+aqFypEWMePnhNrfnUiXUEKm6Xp0vgU=
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pion/datachannel v1.4.17 h1:8CChK5VrJoGrwKCysoTscoWvshCAFpUkgY11Tqgz5hE=
github.com/pion/datachannel v1.4.17/go.mod h1:+vPQfypU9vSsyPXogYj1hBThWQ6MNXEQoQAzxoPvjYM=
github.com/pion/dtls/v2 v2.0.0 h1:Fk+MBhLZ/U1bImzAhmzwbO/pP2rKhtTw8iA934H3ybE=
github.com/pion/dtls/v2 v2.0.0/go.mod h1:VkY5VL2wtsQQOG60xQ4lkV5pdn0wwBBTzCfRJqXhp3A=
github.com/pion/ice v0.7.15 h1:s1In+gnuyVq7WKWGVQL+1p+OcrMsbfL+VfSe2isH8Ag=
github.com/pion/ice v0.7.15/go.mod h1:Z6zybEQgky5mZkKcLfmvc266JukK2srz3VZBBD1iXBw=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/pion/datachannel v1.4.21 h1:3ZvhNyfmxsAqltQrApLPQMhSFNA+aT87RqyCq4OXmf0=
github.com/pion/datachannel v1.4.21/go.mod h1:oiNyP4gHx2DIwRzX/MFyH0Rz/Gz05OgBlayAI2hAWjg=
github.com/pion/dtls/v2 v2.0.4 h1:WuUcqi6oYMu/noNTz92QrF1DaFj4eXbhQ6dzaaAwOiI=
github.com/pion/dtls/v2 v2.0.4/go.mod h1:qAkFscX0ZHoI1E07RfYPoRw3manThveu+mlTDdOxoGI=
github.com/pion/ice/v2 v2.0.14 h1:FxXxauyykf89SWAtkQCfnHkno6G8+bhRkNguSh9zU+4=
github.com/pion/ice/v2 v2.0.14/go.mod h1:wqaUbOq5ObDNU5ox1hRsEst0rWfsKuH1zXjQFEWiZwM=
github.com/pion/interceptor v0.0.9 h1:fk5hTdyLO3KURQsf/+RjMpEm4NE3yeTY9Kh97b5BvwA=
github.com/pion/interceptor v0.0.9/go.mod h1:dHgEP5dtxOTf21MObuBAjJeAayPxLUAZjerGH8Xr07c=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns v0.0.4 h1:O4vvVqr4DGX63vzmO6Fw9vpy3lfztVWHGCQfyw0ZLSY=
github.com/pion/mdns v0.0.4/go.mod h1:R1sL0p50l42S5lJs91oNdUL58nm0QHrhxnSegr++qC0=
github.com/pion/quic v0.1.1 h1:D951FV+TOqI9A0rTF7tHx0Loooqz+nyzjEyj8o3PuMA=
github.com/pion/quic v0.1.1/go.mod h1:zEU51v7ru8Mp4AUBJvj6psrSth5eEFNnVQK5K48oV3k=
github.com/pion/randutil v0.0.0 h1:aLWLVhTG2jzoD25F0OlW6nXvXrjoGwiXq2Sz7j7NzL0=
github.com/pion/randutil v0.0.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
github.com/pion/rtcp v1.2.1 h1:S3yG4KpYAiSmBVqKAfgRa5JdwBNj4zK3RLUa8JYdhak=
github.com/pion/rtcp v1.2.1/go.mod h1:a5dj2d6BKIKHl43EnAOIrCczcjESrtPuMgfmL6/K6QM=
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
github.com/pion/rtcp v1.2.6 h1:1zvwBbyd0TeEuuWftrd/4d++m+/kZSeiguxU61LFWpo=
github.com/pion/rtcp v1.2.6/go.mod h1:52rMNPWFsjr39z9B9MhnkqhPLoeHTv1aN63o/42bWE0=
github.com/pion/rtp v1.5.4 h1:PuNg6xqV3brIUihatcKZj1YDUs+M45L0ZbrZWYtkDxY=
github.com/pion/rtp v1.5.4/go.mod h1:bg60AL5GotNOlYZsqycbhDtEV3TkfbpXG0KBiUq29Mg=
github.com/pion/rtp v1.6.0 h1:4Ssnl/T5W2LzxHj9ssYpGVEQh3YYhQFNVmSWO88MMwk=
github.com/pion/rtp v1.6.0/go.mod h1:QgfogHsMBVE/RFNno467U/KBqfUywEH+HK+0rtnwsdI=
github.com/pion/sctp v1.7.6 h1:8qZTdJtbKfAns/Hv5L0PAj8FyXcsKhMH1pKUCGisQg4=
github.com/pion/sctp v1.7.6/go.mod h1:ichkYQ5tlgCQwEwvgfdcAolqx1nHbYCxo4D7zK/K0X8=
github.com/pion/sdp/v2 v2.3.7 h1:WUZHI3pfiYCaE8UGUYcabk863LCK+Bq3AklV5O0oInQ=
github.com/pion/sdp/v2 v2.3.7/go.mod h1:+ZZf35r1+zbaWYiZLfPutWfx58DAWcGb2QsS3D/s9M8=
github.com/pion/srtp v1.3.3 h1:8bjs9YaSNvSrbH0OfKxzPX+PTrCyAC2LoT9Qesugi+U=
github.com/pion/srtp v1.3.3/go.mod h1:jNe0jmIOqksuurR9S/7yoKDalfPeluUFrNPCBqI4FOI=
github.com/pion/stun v0.3.3 h1:brYuPl9bN9w/VM7OdNzRSLoqsnwlyNvD9MVeJrHjDQw=
github.com/pion/stun v0.3.3/go.mod h1:xrCld6XM+6GWDZdvjPlLMsTU21rNxnO6UO8XsAvHr/M=
github.com/pion/rtp v1.6.2 h1:iGBerLX6JiDjB9NXuaPzHyxHFG9JsIEdgwTC0lp5n/U=
github.com/pion/rtp v1.6.2/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/pion/sctp v1.7.10 h1:o3p3/hZB5Cx12RMGyWmItevJtZ6o2cpuxaw6GOS4x+8=
github.com/pion/sctp v1.7.10/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0=
github.com/pion/sctp v1.7.11 h1:UCnj7MsobLKLuP/Hh+JMiI/6W5Bs/VF45lWKgHFjSIE=
github.com/pion/sctp v1.7.11/go.mod h1:EhpTUQu1/lcK3xI+eriS6/96fWetHGCvBi9MSsnaBN0=
github.com/pion/sdp/v3 v3.0.4 h1:2Kf+dgrzJflNCSw3TV5v2VLeI0s/qkzy2r5jlR0wzf8=
github.com/pion/sdp/v3 v3.0.4/go.mod h1:bNiSknmJE0HYBprTHXKPQ3+JjacTv5uap92ueJZKsRk=
github.com/pion/srtp/v2 v2.0.1 h1:kgfh65ob3EcnFYA4kUBvU/menCp9u7qaJLXwWgpobzs=
github.com/pion/srtp/v2 v2.0.1/go.mod h1:c8NWHhhkFf/drmHTAblkdu8++lsISEBBdAuiyxgqIsE=
github.com/pion/stun v0.3.5 h1:uLUCBCkQby4S1cf6CGuR9QrVOKcvUwFeemaC865QHDg=
github.com/pion/stun v0.3.5/go.mod h1:gDMim+47EeEtfWogA37n6qXZS88L5V6LqFcf+DZA2UA=
github.com/pion/transport v0.6.0/go.mod h1:iWZ07doqOosSLMhZ+FXUTq+TamDoXSllxpbGcfkCmbE=
github.com/pion/transport v0.8.9/go.mod h1:lpeSM6KJFejVtZf8k0fgeN7zE73APQpTF83WvA1FVP8=
github.com/pion/transport v0.8.10/go.mod h1:tBmha/UCjpum5hqTWhfAEs3CO4/tHSg0MYRhSzR+CZ8=
github.com/pion/transport v0.10.0 h1:9M12BSneJm6ggGhJyWpDveFOstJsTiQjkLf4M44rm80=
github.com/pion/transport v0.10.0/go.mod h1:BnHnUipd0rZQyTVB2SBGojFHT9CBt5C5TcsJSQGkvSE=
github.com/pion/transport v0.10.1 h1:2W+yJT+0mOQ160ThZYUx5Zp2skzshiNgxrNE9GUfhJM=
github.com/pion/transport v0.10.1/go.mod h1:PBis1stIILMiis0PewDw91WJeLJkyIMcEk+DwKOzf4A=
github.com/pion/turn v1.4.0 h1:7NUMRehQz4fIo53Qv9ui1kJ0Kr1CA82I81RHKHCeM80=
github.com/pion/turn v1.4.0/go.mod h1:aDSi6hWX/hd1+gKia9cExZOR0MU95O7zX9p3Gw/P2aU=
github.com/pion/turn/v2 v2.0.3 h1:SJUUIbcPoehlyZgMyIUbBBDhI03sBx32x3JuSIBKBWA=
github.com/pion/turn/v2 v2.0.3/go.mod h1:kl1hmT3NxcLynpXVnwJgObL8C9NaCyPTeqI2DcCpSZs=
github.com/pion/turn/v2 v2.0.4 h1:oDguhEv2L/4rxwbL9clGLgtzQPjtuZwCdoM7Te8vQVk=
github.com/pion/turn/v2 v2.0.4/go.mod h1:1812p4DcGVbYVBTiraUmP50XoKye++AMkbfp+N27mog=
github.com/pion/webrtc/v2 v2.2.14 h1:bRjnXTqMDJ3VERPF45z439Sv6QfDfjdYvdQk1QcIx8M=
github.com/pion/webrtc/v2 v2.2.14/go.mod h1:G+8lShCMbHhjpMF1ZJBkyuvrxXrvW4bxs3nOt+mJ2UI=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pion/transport v0.12.0/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q=
github.com/pion/transport v0.12.2 h1:WYEjhloRHt1R86LhUKjC5y+P52Y11/QqEUalvtzVoys=
github.com/pion/transport v0.12.2/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q=
github.com/pion/turn/v2 v2.0.5 h1:iwMHqDfPEDEOFzwWKT56eFmh6DYC6o/+xnLAEzgISbA=
github.com/pion/turn/v2 v2.0.5/go.mod h1:APg43CFyt/14Uy7heYUOGWdkem/Wu4PhCO/bjyrTqMw=
github.com/pion/udp v0.1.0 h1:uGxQsNyrqG3GLINv36Ff60covYmfrLoxzwnCsIYspXI=
github.com/pion/udp v0.1.0/go.mod h1:BPELIjbwE9PRbd/zxI/KYBnbo7B6+oA6YuEaNE8lths=
github.com/pion/webrtc/v3 v3.0.4 h1:Tiw3H9fpfcwkvaxonB+Gv1DG9tmgYBQaM1vBagDHP40=
github.com/pion/webrtc/v3 v3.0.4/go.mod h1:1TmFSLpPYFTFXFHPtoq9eGP1ASTa9LC6FBh7sUY8cd4=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quangngotan95/go-m3u8 v0.1.0 h1:8oseBjJn5IKHQKdRZwSNskkua3NLrRtlvXXtoVgBzMk=
github.com/quangngotan95/go-m3u8 v0.1.0/go.mod h1:smzfWHlYpBATVNu1GapKLYiCtEo5JxridIgvvudZ+Wc=
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY=
github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v2.20.7+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v2.20.8+incompatible h1:8c7Atn0FAUZJo+f4wYbN0iVpdWniCQk7IYwGtgdh1mY=
github.com/shirou/gopsutil v2.20.8+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf h1:Z2X3Os7oRzpdJ75iPqWZc0HeJWFYNCvKsfpQwFpRNTA=
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0=
github.com/zhangpeihao/goamf v0.0.0-20140409082417-3ff2c19514a8 h1:r1JUI0wuHlgRb8jNd3zPBBkjUdrjpVKr8SdJWc8ntg8=
github.com/zhangpeihao/goamf v0.0.0-20140409082417-3ff2c19514a8/go.mod h1:RZd/IqzNpFANwOB9rVmsnAYpo/6KesK4PqrN1a5cRgg=
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59 h1:3zb4D3T4G8jdExgVU/95+vQXfpEPiMdCaZgmGVxjNHM=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201029221708-28c70e62bb1d h1:dOiJ2n2cMwGLce/74I/QHMbnpk5GfY7InR8rczoMqRM=
golang.org/x/net v0.0.0-20201029221708-28c70e62bb1d/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7 h1:3uJsdck53FDIpWwLeAXlia9p4C8j0BO2xZrqzKpL0D8=
golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200828161417-c663848e9a16/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -206,8 +181,10 @@ gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

226
main.go

@ -10,12 +10,13 @@ import (
"sync"
"time"
. "github.com/Monibuca/engine/v2"
"github.com/Monibuca/engine/v2/avformat"
"github.com/Monibuca/engine/v3"
. "github.com/Monibuca/plugin-rtp"
"github.com/Monibuca/utils/v3"
"github.com/Monibuca/utils/v3/codec"
"github.com/pion/rtcp"
. "github.com/pion/webrtc/v2"
"github.com/pion/webrtc/v2/pkg/media"
. "github.com/pion/webrtc/v3"
"github.com/pion/webrtc/v3/pkg/media"
)
var config struct {
@ -75,10 +76,9 @@ func (wl *WaitList) Get(k string) *WebRTC {
return wl.m[k]
}
func init() {
InstallPlugin(&PluginConfig{
engine.InstallPlugin(&engine.PluginConfig{
Config: &config,
Name: "WebRTC",
Type: PLUGIN_PUBLISHER | PLUGIN_SUBSCRIBER,
Run: run,
})
}
@ -87,93 +87,111 @@ type WebRTC struct {
RTP
*PeerConnection
RemoteAddr string
audioTrack *Track
videoTrack *Track
audioTrack *TrackLocalStaticSample
videoTrack *TrackLocalStaticSample
m MediaEngine
s SettingEngine
api *API
payloader avformat.H264
payloader codec.H264
// codecs.H264Packet
// *os.File
}
func (rtc *WebRTC) Play(streamPath string) bool {
var sub Subscriber
var sub engine.Subscriber
sub.ID = rtc.RemoteAddr
sub.Type = "WebRTC"
var lastTimeStampV, lastTiimeStampA uint32
sub.OnData = func(packet *avformat.SendPacket) error {
if packet.Type == avformat.FLV_TAG_TYPE_AUDIO {
var s uint32
if lastTiimeStampA > 0 {
s = packet.Timestamp - lastTiimeStampA
}
lastTiimeStampA = packet.Timestamp
rtc.audioTrack.WriteSample(media.Sample{
Data: packet.Payload[1:],
Samples: s * 8,
})
return nil
}
if packet.IsSequence {
rtc.payloader.PPS = sub.PPS
rtc.payloader.SPS = sub.SPS
} else {
var s uint32
onVideo := func(pack engine.VideoPack){
var s uint32
if lastTimeStampV > 0 {
s = packet.Timestamp - lastTimeStampV
s = pack.Timestamp - lastTimeStampV
}
lastTimeStampV = packet.Timestamp
rtc.videoTrack.WriteSample(media.Sample{
Data: packet.Payload,
Samples: s * 90,
})
// if packet.IsKeyFrame {
// rtc.videoTrack.WriteSample(media.Sample{
// Data: sub.SPS,
// Samples: 0,
// })
// rtc.videoTrack.WriteSample(media.Sample{
// Data: sub.PPS,
// Samples: 0,
// })
// }
// for payload := packet.Payload[5:]; len(payload) > 4; {
// var naulLen = int(util.BigEndian.Uint32(payload))
// payload = payload[4:]
// rtc.videoTrack.WriteSample(media.Sample{
// Data: payload[:naulLen],
// Samples: s * 90,
// })
// s = 0
// payload = payload[naulLen:]
// }
}
return nil
lastTimeStampV = pack.Timestamp
if pack.NalType == codec.NALU_IDR_Picture {
rtc.videoTrack.WriteSample(media.Sample{
Data:sub.VideoTracks[0].SPS,
})
rtc.videoTrack.WriteSample(media.Sample{
Data:sub.VideoTracks[0].PPS,
})
}
rtc.videoTrack.WriteSample(media.Sample{
Data:pack.Payload,
Duration:time.Millisecond*time.Duration(s),
})
}
onAudio := func(pack engine.AudioPack){
var s uint32
if lastTiimeStampA > 0 {
s = pack.Timestamp - lastTiimeStampA
}
lastTiimeStampA = pack.Timestamp
rtc.audioTrack.WriteSample(media.Sample{
Data:pack.Payload,Duration: time.Millisecond*time.Duration(s),
})
}
// sub.OnData = func(packet *codec.SendPacket) error {
// if packet.Type == codec.FLV_TAG_TYPE_AUDIO {
// var s uint32
// if lastTiimeStampA > 0 {
// s = packet.Timestamp - lastTiimeStampA
// }
// lastTiimeStampA = packet.Timestamp
// rtc.audioTrack.WriteSample(media.Sample{
// Data: packet.Payload[1:],
// Samples: s * 8,
// })
// return nil
// }
// if packet.IsSequence {
// rtc.payloader.PPS = sub.PPS
// rtc.payloader.SPS = sub.SPS
// } else {
// var s uint32
// if lastTimeStampV > 0 {
// s = packet.Timestamp - lastTimeStampV
// }
// lastTimeStampV = packet.Timestamp
// rtc.videoTrack.WriteSample(media.Sample{
// Data: packet.Payload,
// Samples: s * 90,
// })
// }
// return nil
// }
// go sub.Subscribe(streamPath)
rtc.OnICEConnectionStateChange(func(connectionState ICEConnectionState) {
Printf("%s Connection State has changed %s ", streamPath, connectionState.String())
utils.Printf("%s Connection State has changed %s ", streamPath, connectionState.String())
switch connectionState {
case ICEConnectionStateDisconnected:
sub.Close()
rtc.Close()
case ICEConnectionStateConnected:
//rtc.videoTrack = rtc.GetSenders()[0].Track()
sub.Subscribe(streamPath)
if err := sub.Subscribe(streamPath);err== nil {
go sub.VideoTracks[0].Play(sub.Context,onVideo)
go sub.AudioTracks[0].Play(sub.Context,onAudio)
}
}
})
return true
}
func (rtc *WebRTC) Publish(streamPath string) bool {
rtc.m.RegisterCodec(NewRTPCodec(RTPCodecTypeVideo,
H264,
90000,
0,
"level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f",
DefaultPayloadTypeH264,
new(avformat.H264)))
rtc.m.RegisterDefaultCodecs()
// rtc.m.RegisterCodec(NewRTPCodec(RTPCodecTypeVideo,
// H264,
// 90000,
// 0,
// "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f",
// DefaultPayloadTypeH264,
// new(codec.H264)))
// rtc.m.RegisterCodec(RTPCodecParameters{
// RTPCodecCapability: RTPCodecCapability{MimeType: "video/h264", ClockRate: 90000, Channels: 0, SDPFmtpLine: "", RTCPFeedback: nil},
// PayloadType: 96,
// }, RTPCodecTypeVideo);
//m.RegisterCodec(NewRTPPCMUCodec(DefaultPayloadTypePCMU, 8000))
if !strings.HasPrefix(rtc.RemoteAddr, "127.0.0.1") && !strings.HasPrefix(rtc.RemoteAddr, "[::1]") {
rtc.s.SetNAT1To1IPs(config.PublicIP, ICECandidateTypeHost)
@ -181,7 +199,7 @@ func (rtc *WebRTC) Publish(streamPath string) bool {
if config.PortMin > 0 && config.PortMax > 0 {
rtc.s.SetEphemeralUDPPortRange(config.PortMin, config.PortMax)
}
rtc.api = NewAPI(WithMediaEngine(rtc.m), WithSettingEngine(rtc.s))
rtc.api = NewAPI(WithMediaEngine(&rtc.m), WithSettingEngine(rtc.s))
peerConnection, err := rtc.api.NewPeerConnection(Configuration{
ICEServers: []ICEServer{
{
@ -190,12 +208,12 @@ func (rtc *WebRTC) Publish(streamPath string) bool {
},
})
if err != nil {
Println(err)
utils.Println(err)
return false
}
if _, err = peerConnection.AddTransceiverFromKind(RTPCodecTypeVideo); err != nil {
if err != nil {
Println(err)
utils.Println(err)
return false
}
}
@ -203,7 +221,7 @@ func (rtc *WebRTC) Publish(streamPath string) bool {
return false
}
peerConnection.OnICEConnectionStateChange(func(connectionState ICEConnectionState) {
Printf("%s Connection State has changed %s ", streamPath, connectionState.String())
utils.Printf("%s Connection State has changed %s ", streamPath, connectionState.String())
switch connectionState {
case ICEConnectionStateDisconnected, ICEConnectionStateFailed:
if rtc.Stream != nil {
@ -215,13 +233,13 @@ func (rtc *WebRTC) Publish(streamPath string) bool {
if rtc.RTP.Publish(streamPath) {
//f, _ := os.OpenFile("resource/live/rtc.h264", os.O_TRUNC|os.O_WRONLY, 0666)
rtc.Stream.Type = "WebRTC"
peerConnection.OnTrack(func(track *Track, receiver *RTPReceiver) {
peerConnection.OnTrack(func(track *TrackRemote, receiver *RTPReceiver) {
defer rtc.Stream.Close()
go func() {
ticker := time.NewTicker(time.Second * 2)
select {
case <-ticker.C:
if rtcpErr := peerConnection.WriteRTCP([]rtcp.Packet{&rtcp.PictureLossIndication{MediaSSRC: track.SSRC()}}); rtcpErr != nil {
if rtcpErr := peerConnection.WriteRTCP([]rtcp.Packet{&rtcp.PictureLossIndication{MediaSSRC: uint32(track.SSRC())}}); rtcpErr != nil {
fmt.Println(rtcpErr)
}
case <-rtc.Done():
@ -232,7 +250,7 @@ func (rtc *WebRTC) Publish(streamPath string) bool {
Type: RTPType(track.Kind() - 1),
}
for b := make([]byte, 1460); ; rtc.PushPack(pack) {
i, err := track.Read(b)
i,_, err := track.Read(b)
if err != nil {
return
}
@ -254,12 +272,13 @@ func (rtc *WebRTC) GetAnswer() ([]byte, error) {
if err != nil {
return nil, err
}
//gatherComplete := webrtc.GatheringCompletePromise(rtc.PeerConnection)
if err := rtc.SetLocalDescription(answer); err != nil {
Println(err)
utils.Println(err)
return nil, err
}
if bytes, err := json.Marshal(answer); err != nil {
Println(err)
utils.Println(err)
return bytes, err
} else {
return bytes, nil
@ -284,7 +303,7 @@ func run() {
bytes, err := ioutil.ReadAll(r.Body)
defer func() {
if err != nil {
Println(err)
utils.Println(err)
fmt.Fprintf(w, `{"errmsg":"%s"}`, err)
return
}
@ -298,28 +317,35 @@ func run() {
}
pli := "42001f"
if stream := FindStream(streamPath); stream != nil {
if stream := engine.FindStream(streamPath); stream != nil {
<-stream.WaitPub
pli = fmt.Sprintf("%x", stream.SPS[1:4])
pli = fmt.Sprintf("%x", stream.VideoTracks[0].SPS[1:4])
}
if !strings.Contains(offer.SDP, pli) {
pli = reg_level.FindAllStringSubmatch(offer.SDP, -1)[0][1]
}
rtc.m.RegisterCodec(NewRTPCodec(RTPCodecTypeVideo,
H264,
90000,
0,
"level-asymmetry-allowed=1;packetization-mode=1;profile-level-id="+pli,
DefaultPayloadTypeH264,
&rtc.payloader))
rtc.m.RegisterCodec(NewRTPPCMACodec(DefaultPayloadTypePCMA, 8000))
if !strings.HasPrefix(r.RemoteAddr, "127.0.0.1") && !strings.HasPrefix(r.RemoteAddr, "[::1]") {
rtc.s.SetNAT1To1IPs(config.PublicIP, ICECandidateTypeHost)
}
// rtc.m.RegisterCodec(NewRTPCodec(RTPCodecTypeVideo,
// H264,
// 90000,
// 0,
// "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id="+pli,
// DefaultPayloadTypeH264,
// &rtc.payloader))
rtc.m.RegisterDefaultCodecs()
// rtc.m.RegisterCodec(RTPCodecParameters{
// RTPCodecCapability: RTPCodecCapability{MimeType: "video/h264", ClockRate: 90000, Channels: 0, SDPFmtpLine: "", RTCPFeedback: nil},
// PayloadType: 102,
// }, RTPCodecTypeVideo);
// rtc.m.RegisterCodec(NewRTPPCMACodec(DefaultPayloadTypePCMA, 8000))
// if !strings.HasPrefix(r.RemoteAddr, "127.0.0.1") && !strings.HasPrefix(r.RemoteAddr, "[::1]") {
// rtc.s.SetNAT1To1IPs(config.PublicIP, ICECandidateTypeHost)
// }
if config.PortMin > 0 && config.PortMax > 0 {
rtc.s.SetEphemeralUDPPortRange(config.PortMin, config.PortMax)
}
rtc.api = NewAPI(WithMediaEngine(rtc.m), WithSettingEngine(rtc.s))
rtc.api = NewAPI(WithMediaEngine(&rtc.m), WithSettingEngine(rtc.s))
if rtc.PeerConnection, err = rtc.api.NewPeerConnection(Configuration{
// ICEServers: []ICEServer{
@ -332,7 +358,7 @@ func run() {
}
rtc.OnICECandidate(func(ice *ICECandidate) {
if ice != nil {
Println(ice.ToJSON().Candidate)
utils.Println(ice.ToJSON().Candidate)
}
})
// if r, err := peerConnection.AddTransceiverFromKind(RTPCodecTypeVideo); err == nil {
@ -356,10 +382,14 @@ func run() {
// }
// }
// println(vpayloadType)
if rtc.videoTrack, err = rtc.NewTrack(DefaultPayloadTypeH264, 8, "video", "monibuca"); err != nil {
return
}
if rtc.audioTrack, err = rtc.NewTrack(DefaultPayloadTypePCMA, 9, "audio", "monibuca"); err != nil {
// if rtc.videoTrack, err = rtc.Track(DefaultPayloadTypeH264, 8, "video", "monibuca"); err != nil {
// return
// }
// if rtc.audioTrack, err = rtc.Track(DefaultPayloadTypePCMA, 9, "audio", "monibuca"); err != nil {
// return
// }
if rtc.videoTrack,err = NewTrackLocalStaticSample(RTPCodecCapability{MimeType:"video/h264",SDPFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id="+pli},"video","m7s");err!=nil{
return
}
if _, err = rtc.AddTrack(rtc.videoTrack); err != nil {
@ -378,20 +408,20 @@ func run() {
bytes, err := ioutil.ReadAll(r.Body)
err = json.Unmarshal(bytes, &offer)
if err != nil {
Println(err)
utils.Println(err)
return
}
rtc := new(WebRTC)
rtc.RemoteAddr = r.RemoteAddr
if rtc.Publish(streamPath) {
if err := rtc.SetRemoteDescription(offer); err != nil {
Println(err)
utils.Println(err)
return
}
if bytes, err = rtc.GetAnswer(); err == nil {
w.Write(bytes)
} else {
Println(err)
utils.Println(err)
w.Write([]byte(err.Error()))
return
}

19
ui/dist/demo.html

@ -1,19 +0,0 @@
<meta charset="utf-8">
<title>plugin-webrtc demo</title>
<script src="https://unpkg.com/vue"></script>
<script src="./plugin-webrtc.umd.js"></script>
<link rel="stylesheet" href="./plugin-webrtc.css">
<div id="app">
<demo></demo>
</div>
<script>
new Vue({
components: {
demo: plugin-webrtc
}
}).$mount('#app')
</script>

584
ui/dist/plugin-webrtc.common.js

@ -1,584 +0,0 @@
module.exports =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "fb15");
/******/ })
/************************************************************************/
/******/ ({
/***/ "2029":
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "8875":
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// addapted from the document.currentScript polyfill by Adam Miller
// MIT license
// source: https://github.com/amiller-gh/currentScript-polyfill
// added support for Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1620505
(function (root, factory) {
if (true) {
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
} else {}
}(typeof self !== 'undefined' ? self : this, function () {
function getCurrentScript () {
if (document.currentScript) {
return document.currentScript
}
// IE 8-10 support script readyState
// IE 11+ & Firefox support stack trace
try {
throw new Error();
}
catch (err) {
// Find the second match for the "at" string to get file src url from stack.
var ieStackRegExp = /.*at [^(]*\((.*):(.+):(.+)\)$/ig,
ffStackRegExp = /@([^@]*):(\d+):(\d+)\s*$/ig,
stackDetails = ieStackRegExp.exec(err.stack) || ffStackRegExp.exec(err.stack),
scriptLocation = (stackDetails && stackDetails[1]) || false,
line = (stackDetails && stackDetails[2]) || false,
currentLocation = document.location.href.replace(document.location.hash, ''),
pageSource,
inlineScriptSourceRegExp,
inlineScriptSource,
scripts = document.getElementsByTagName('script'); // Live NodeList collection
if (scriptLocation === currentLocation) {
pageSource = document.documentElement.outerHTML;
inlineScriptSourceRegExp = new RegExp('(?:[^\\n]+?\\n){0,' + (line - 2) + '}[^<]*<script>([\\d\\D]*?)<\\/script>[\\d\\D]*', 'i');
inlineScriptSource = pageSource.replace(inlineScriptSourceRegExp, '$1').trim();
}
for (var i = 0; i < scripts.length; i++) {
// If ready state is interactive, return the script tag
if (scripts[i].readyState === 'interactive') {
return scripts[i];
}
// If src matches, return the script tag
if (scripts[i].src === scriptLocation) {
return scripts[i];
}
// If inline source matches, return the script tag
if (
scriptLocation === currentLocation &&
scripts[i].innerHTML &&
scripts[i].innerHTML.trim() === inlineScriptSource
) {
return scripts[i];
}
}
// If no match, return null
return null;
}
};
return getCurrentScript
}));
/***/ }),
/***/ "bce4":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_674ea55a_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("2029");
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_674ea55a_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_674ea55a_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__);
/* unused harmony reexport * */
/* unused harmony default export */ var _unused_webpack_default_export = (_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_674ea55a_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/***/ }),
/***/ "fb15":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/setPublicPath.js
// This file is imported into lib/wc client bundles.
if (typeof window !== 'undefined') {
var currentScript = window.document.currentScript
if (true) {
var getCurrentScript = __webpack_require__("8875")
currentScript = getCurrentScript()
// for backward compatibility, because previously we directly included the polyfill
if (!('currentScript' in document)) {
Object.defineProperty(document, 'currentScript', { get: getCurrentScript })
}
}
var src = currentScript && currentScript.src.match(/(.+\/)[^/]+\.js(\?.*)?$/)
if (src) {
__webpack_require__.p = src[1] // eslint-disable-line
}
}
// Indicate to webpack that this file can be concatenated
/* harmony default export */ var setPublicPath = (null);
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"0b526416-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=template&id=674ea55a&scoped=true&
var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[(_vm.$parent.titleTabActive == 0)?_c('div',[_c('mu-text-field',{attrs:{"label":"streamPath"},model:{value:(_vm.streamPath),callback:function ($$v) {_vm.streamPath=$$v},expression:"streamPath"}}),(!_vm.remoteSDP)?_c('m-button',{on:{"click":_vm.publish}},[_vm._v("Publish")]):_c('m-button',{on:{"click":_vm.stopSession}},[_vm._v("Stop")]),(_vm.remoteSDP)?_c('mu-badge',[_c('a',{attrs:{"slot":"content","href":_vm.remoteSDPURL,"download":"remoteSDP.txt"},slot:"content"},[_vm._v("remoteSDP")])]):_vm._e(),(_vm.localSDP)?_c('mu-badge',[_c('a',{attrs:{"slot":"content","href":_vm.localSDPURL,"download":"localSDP.txt"},slot:"content"},[_vm._v("localSDP")])]):_vm._e(),_c('br'),_c('video',{ref:"video1",attrs:{"width":"640","height":"480","autoplay":"","muted":""},domProps:{"srcObject":_vm.stream,"muted":true}})],1):(_vm.$parent.titleTabActive == 1)?_c('stream-table',{scopedSlots:_vm._u([{key:"default",fn:function(scope){return [_c('m-button',{on:{"click":function($event){return _vm.preview(scope)}}},[_vm._v("Play")]),void 0]}}])}):(_vm.$parent.titleTabActive == 2)?_c('pre',[_vm._v(_vm._s(_vm.localSDP))]):(_vm.$parent.titleTabActive == 3)?_c('pre',[_vm._v(_vm._s(_vm.remoteSDP))]):_vm._e(),_c('webrtc-player',{ref:"player",attrs:{"PublicIP":_vm.PublicIP},model:{value:(_vm.previewStreamPath),callback:function ($$v) {_vm.previewStreamPath=$$v},expression:"previewStreamPath"}})],1)}
var staticRenderFns = []
// CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=674ea55a&scoped=true&
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"0b526416-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/Player.vue?vue&type=template&id=30c7d0b2&
var Playervue_type_template_id_30c7d0b2_render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('Modal',_vm._g(_vm._b({attrs:{"draggable":"","title":_vm.streamPath},on:{"on-ok":_vm.onClosePreview,"on-cancel":_vm.onClosePreview}},'Modal',_vm.$attrs,false),_vm.$listeners),[_c('video',{ref:"webrtc",attrs:{"width":"488","height":"275","autoplay":"","muted":"","controls":""},domProps:{"srcObject":_vm.stream,"muted":true}}),_c('div',{attrs:{"slot":"footer"},slot:"footer"},[(_vm.remoteSDP)?_c('mu-badge',[_c('a',{attrs:{"slot":"content","href":_vm.remoteSDPURL,"download":"remoteSDP.txt"},slot:"content"},[_vm._v("remoteSDP")])]):_vm._e(),(_vm.localSDP)?_c('mu-badge',[_c('a',{attrs:{"slot":"content","href":_vm.localSDPURL,"download":"localSDP.txt"},slot:"content"},[_vm._v("localSDP")])]):_vm._e()],1)])}
var Playervue_type_template_id_30c7d0b2_staticRenderFns = []
// CONCATENATED MODULE: ./src/components/Player.vue?vue&type=template&id=30c7d0b2&
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/Player.vue?vue&type=script&lang=js&
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
let pc = null;
/* harmony default export */ var Playervue_type_script_lang_js_ = ({
data() {
return {
iceConnectionState: pc && pc.iceConnectionState,
stream: null,
localSDP: "",
remoteSDP: "",
remoteSDPURL: "",
localSDPURL: "",
streamPath: ""
};
},
props:{
PublicIP:String
},
methods: {
async play(streamPath) {
pc = new RTCPeerConnection();
pc.addTransceiver('video',{
direction:'recvonly'
})
this.streamPath = streamPath;
pc.onsignalingstatechange = e => {
//console.log(e);
};
pc.oniceconnectionstatechange = e => {
this.$toast.info(pc.iceConnectionState);
this.iceConnectionState = pc.iceConnectionState;
};
pc.onicecandidate = event => {
console.log(event)
};
pc.ontrack = event => {
// console.log(event);
if (event.track.kind == "video")
this.stream = event.streams[0];
};
await pc.setLocalDescription(await pc.createOffer());
this.localSDP = pc.localDescription.sdp;
this.localSDPURL = URL.createObjectURL(
new Blob([this.localSDP], { type: "text/plain" })
);
const result = await this.ajax({
type: "POST",
processData: false,
data: JSON.stringify(pc.localDescription.toJSON()),
url: "/webrtc/play?streamPath=" + this.streamPath,
dataType: "json"
});
if (result.errmsg) {
this.$toast.error(result.errmsg);
return;
} else {
this.remoteSDP = result.sdp;
this.remoteSDPURL = URL.createObjectURL(new Blob([this.remoteSDP], { type: "text/plain" }));
}
await pc.setRemoteDescription(new RTCSessionDescription(result));
},
onClosePreview() {
pc.close();
}
}
});
// CONCATENATED MODULE: ./src/components/Player.vue?vue&type=script&lang=js&
/* harmony default export */ var components_Playervue_type_script_lang_js_ = (Playervue_type_script_lang_js_);
// CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
/* globals __VUE_SSR_CONTEXT__ */
// IMPORTANT: Do NOT use ES2015 features in this file (except for modules).
// This module is a runtime utility for cleaner component module output and will
// be included in the final webpack user bundle.
function normalizeComponent (
scriptExports,
render,
staticRenderFns,
functionalTemplate,
injectStyles,
scopeId,
moduleIdentifier, /* server only */
shadowMode /* vue-cli only */
) {
// Vue.extend constructor export interop
var options = typeof scriptExports === 'function'
? scriptExports.options
: scriptExports
// render functions
if (render) {
options.render = render
options.staticRenderFns = staticRenderFns
options._compiled = true
}
// functional template
if (functionalTemplate) {
options.functional = true
}
// scopedId
if (scopeId) {
options._scopeId = 'data-v-' + scopeId
}
var hook
if (moduleIdentifier) { // server build
hook = function (context) {
// 2.3 injection
context =
context || // cached call
(this.$vnode && this.$vnode.ssrContext) || // stateful
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional
// 2.2 with runInNewContext: true
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__
}
// inject component styles
if (injectStyles) {
injectStyles.call(this, context)
}
// register component module identifier for async chunk inferrence
if (context && context._registeredComponents) {
context._registeredComponents.add(moduleIdentifier)
}
}
// used by ssr in case component is cached and beforeCreate
// never gets called
options._ssrRegister = hook
} else if (injectStyles) {
hook = shadowMode
? function () {
injectStyles.call(
this,
(options.functional ? this.parent : this).$root.$options.shadowRoot
)
}
: injectStyles
}
if (hook) {
if (options.functional) {
// for template-only hot-reload because in that case the render fn doesn't
// go through the normalizer
options._injectStyles = hook
// register for functional component in vue file
var originalRender = options.render
options.render = function renderWithStyleInjection (h, context) {
hook.call(context)
return originalRender(h, context)
}
} else {
// inject component registration as beforeCreate hook
var existing = options.beforeCreate
options.beforeCreate = existing
? [].concat(existing, hook)
: [hook]
}
}
return {
exports: scriptExports,
options: options
}
}
// CONCATENATED MODULE: ./src/components/Player.vue
/* normalize component */
var component = normalizeComponent(
components_Playervue_type_script_lang_js_,
Playervue_type_template_id_30c7d0b2_render,
Playervue_type_template_id_30c7d0b2_staticRenderFns,
false,
null,
null,
null
)
/* harmony default export */ var Player = (component.exports);
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=script&lang=js&
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
const config = { iceServers: []};
let Appvue_type_script_lang_js_pc = new RTCPeerConnection(config);
var stream = null
var streamPath = "live/rtc";
/* harmony default export */ var Appvue_type_script_lang_js_ = ({
components:{
WebrtcPlayer: Player
},
props:{
PublicIP:String
},
data() {
return {
localSDP: Appvue_type_script_lang_js_pc && Appvue_type_script_lang_js_pc.localDescription && Appvue_type_script_lang_js_pc.localDescription.sdp,
remoteSDP: Appvue_type_script_lang_js_pc && Appvue_type_script_lang_js_pc.remoteDescription && Appvue_type_script_lang_js_pc.remoteDescription.sdp,
streamPath,
iceConnectionState: Appvue_type_script_lang_js_pc && Appvue_type_script_lang_js_pc.iceConnectionState,
stream,
previewStreamPath:false,
localSDPURL:"",
remoteSDPURL:""
};
},
methods: {
async publish() {
Appvue_type_script_lang_js_pc.addStream(stream);
await Appvue_type_script_lang_js_pc.setLocalDescription(await Appvue_type_script_lang_js_pc.createOffer());
this.localSDP = Appvue_type_script_lang_js_pc.localDescription.sdp;
this.localSDPURL = URL.createObjectURL(new Blob([ this.localSDP ],{type:'text/plain'}))
const result = await this.ajax({
type: "POST",
processData: false,
data: JSON.stringify(Appvue_type_script_lang_js_pc.localDescription),
url: "/webrtc/publish?streamPath=" + this.streamPath,
dataType: "json"
});
console.log(result)
if (typeof result == "string"){
this.$toast.error(result);
return;
}
streamPath = this.streamPath;
this.remoteSDP = result.sdp;
this.remoteSDPURL = URL.createObjectURL(new Blob([ this.remoteSDP ],{type:'text/plain'}))
Appvue_type_script_lang_js_pc.setRemoteDescription(new RTCSessionDescription(result));
},
stopSession() {
Appvue_type_script_lang_js_pc.close();
Appvue_type_script_lang_js_pc = new RTCPeerConnection(config);
this.remoteSDP = "";
this.localSDP = "";
// this.connectICE().catch(err => this.$toast.error(err.message));
},
preview({row}) {
this.previewStreamPath = true
this.$nextTick(() =>this.$refs.player.play(row.StreamPath));
},
},
async mounted() {
Appvue_type_script_lang_js_pc.onsignalingstatechange = e => {
console.log(e);
};
Appvue_type_script_lang_js_pc.oniceconnectionstatechange = e => {
this.$toast.info(Appvue_type_script_lang_js_pc.iceConnectionState);
this.iceConnectionState = Appvue_type_script_lang_js_pc.iceConnectionState;
};
Appvue_type_script_lang_js_pc.onicecandidate = event => {};
this.$parent.titleTabs = ["publish","play"];
try {
if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia(
{ video: true, audio: true }
);
} catch (err) {
this.$toast.error(err.message);
}
}
});
// CONCATENATED MODULE: ./src/App.vue?vue&type=script&lang=js&
/* harmony default export */ var src_Appvue_type_script_lang_js_ = (Appvue_type_script_lang_js_);
// EXTERNAL MODULE: ./src/App.vue?vue&type=style&index=0&id=674ea55a&scoped=true&lang=css&
var Appvue_type_style_index_0_id_674ea55a_scoped_true_lang_css_ = __webpack_require__("bce4");
// CONCATENATED MODULE: ./src/App.vue
/* normalize component */
var App_component = normalizeComponent(
src_Appvue_type_script_lang_js_,
render,
staticRenderFns,
false,
null,
"674ea55a",
null
)
/* harmony default export */ var App = (App_component.exports);
// CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/entry-lib.js
/* harmony default export */ var entry_lib = __webpack_exports__["default"] = (App);
/***/ })
/******/ })["default"];
//# sourceMappingURL=plugin-webrtc.common.js.map

1
ui/dist/plugin-webrtc.common.js.map

File diff suppressed because one or more lines are too long

1
ui/dist/plugin-webrtc.css

@ -1 +0,0 @@
@-webkit-keyframes blink-data-v-674ea55a{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}@keyframes blink-data-v-674ea55a{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}.blink[data-v-674ea55a]{-webkit-animation:blink-data-v-674ea55a 1s infinite;animation:blink-data-v-674ea55a 1s infinite}

594
ui/dist/plugin-webrtc.umd.js

@ -1,594 +0,0 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["plugin-webrtc"] = factory();
else
root["plugin-webrtc"] = factory();
})((typeof self !== 'undefined' ? self : this), function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "fb15");
/******/ })
/************************************************************************/
/******/ ({
/***/ "2029":
/***/ (function(module, exports, __webpack_require__) {
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "8875":
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// addapted from the document.currentScript polyfill by Adam Miller
// MIT license
// source: https://github.com/amiller-gh/currentScript-polyfill
// added support for Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1620505
(function (root, factory) {
if (true) {
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
} else {}
}(typeof self !== 'undefined' ? self : this, function () {
function getCurrentScript () {
if (document.currentScript) {
return document.currentScript
}
// IE 8-10 support script readyState
// IE 11+ & Firefox support stack trace
try {
throw new Error();
}
catch (err) {
// Find the second match for the "at" string to get file src url from stack.
var ieStackRegExp = /.*at [^(]*\((.*):(.+):(.+)\)$/ig,
ffStackRegExp = /@([^@]*):(\d+):(\d+)\s*$/ig,
stackDetails = ieStackRegExp.exec(err.stack) || ffStackRegExp.exec(err.stack),
scriptLocation = (stackDetails && stackDetails[1]) || false,
line = (stackDetails && stackDetails[2]) || false,
currentLocation = document.location.href.replace(document.location.hash, ''),
pageSource,
inlineScriptSourceRegExp,
inlineScriptSource,
scripts = document.getElementsByTagName('script'); // Live NodeList collection
if (scriptLocation === currentLocation) {
pageSource = document.documentElement.outerHTML;
inlineScriptSourceRegExp = new RegExp('(?:[^\\n]+?\\n){0,' + (line - 2) + '}[^<]*<script>([\\d\\D]*?)<\\/script>[\\d\\D]*', 'i');
inlineScriptSource = pageSource.replace(inlineScriptSourceRegExp, '$1').trim();
}
for (var i = 0; i < scripts.length; i++) {
// If ready state is interactive, return the script tag
if (scripts[i].readyState === 'interactive') {
return scripts[i];
}
// If src matches, return the script tag
if (scripts[i].src === scriptLocation) {
return scripts[i];
}
// If inline source matches, return the script tag
if (
scriptLocation === currentLocation &&
scripts[i].innerHTML &&
scripts[i].innerHTML.trim() === inlineScriptSource
) {
return scripts[i];
}
}
// If no match, return null
return null;
}
};
return getCurrentScript
}));
/***/ }),
/***/ "bce4":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_674ea55a_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("2029");
/* harmony import */ var _node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_674ea55a_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_674ea55a_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0__);
/* unused harmony reexport * */
/* unused harmony default export */ var _unused_webpack_default_export = (_node_modules_mini_css_extract_plugin_dist_loader_js_ref_6_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_App_vue_vue_type_style_index_0_id_674ea55a_scoped_true_lang_css___WEBPACK_IMPORTED_MODULE_0___default.a);
/***/ }),
/***/ "fb15":
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/setPublicPath.js
// This file is imported into lib/wc client bundles.
if (typeof window !== 'undefined') {
var currentScript = window.document.currentScript
if (true) {
var getCurrentScript = __webpack_require__("8875")
currentScript = getCurrentScript()
// for backward compatibility, because previously we directly included the polyfill
if (!('currentScript' in document)) {
Object.defineProperty(document, 'currentScript', { get: getCurrentScript })
}
}
var src = currentScript && currentScript.src.match(/(.+\/)[^/]+\.js(\?.*)?$/)
if (src) {
__webpack_require__.p = src[1] // eslint-disable-line
}
}
// Indicate to webpack that this file can be concatenated
/* harmony default export */ var setPublicPath = (null);
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"0b526416-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=template&id=674ea55a&scoped=true&
var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[(_vm.$parent.titleTabActive == 0)?_c('div',[_c('mu-text-field',{attrs:{"label":"streamPath"},model:{value:(_vm.streamPath),callback:function ($$v) {_vm.streamPath=$$v},expression:"streamPath"}}),(!_vm.remoteSDP)?_c('m-button',{on:{"click":_vm.publish}},[_vm._v("Publish")]):_c('m-button',{on:{"click":_vm.stopSession}},[_vm._v("Stop")]),(_vm.remoteSDP)?_c('mu-badge',[_c('a',{attrs:{"slot":"content","href":_vm.remoteSDPURL,"download":"remoteSDP.txt"},slot:"content"},[_vm._v("remoteSDP")])]):_vm._e(),(_vm.localSDP)?_c('mu-badge',[_c('a',{attrs:{"slot":"content","href":_vm.localSDPURL,"download":"localSDP.txt"},slot:"content"},[_vm._v("localSDP")])]):_vm._e(),_c('br'),_c('video',{ref:"video1",attrs:{"width":"640","height":"480","autoplay":"","muted":""},domProps:{"srcObject":_vm.stream,"muted":true}})],1):(_vm.$parent.titleTabActive == 1)?_c('stream-table',{scopedSlots:_vm._u([{key:"default",fn:function(scope){return [_c('m-button',{on:{"click":function($event){return _vm.preview(scope)}}},[_vm._v("Play")]),void 0]}}])}):(_vm.$parent.titleTabActive == 2)?_c('pre',[_vm._v(_vm._s(_vm.localSDP))]):(_vm.$parent.titleTabActive == 3)?_c('pre',[_vm._v(_vm._s(_vm.remoteSDP))]):_vm._e(),_c('webrtc-player',{ref:"player",attrs:{"PublicIP":_vm.PublicIP},model:{value:(_vm.previewStreamPath),callback:function ($$v) {_vm.previewStreamPath=$$v},expression:"previewStreamPath"}})],1)}
var staticRenderFns = []
// CONCATENATED MODULE: ./src/App.vue?vue&type=template&id=674ea55a&scoped=true&
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"0b526416-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/Player.vue?vue&type=template&id=30c7d0b2&
var Playervue_type_template_id_30c7d0b2_render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('Modal',_vm._g(_vm._b({attrs:{"draggable":"","title":_vm.streamPath},on:{"on-ok":_vm.onClosePreview,"on-cancel":_vm.onClosePreview}},'Modal',_vm.$attrs,false),_vm.$listeners),[_c('video',{ref:"webrtc",attrs:{"width":"488","height":"275","autoplay":"","muted":"","controls":""},domProps:{"srcObject":_vm.stream,"muted":true}}),_c('div',{attrs:{"slot":"footer"},slot:"footer"},[(_vm.remoteSDP)?_c('mu-badge',[_c('a',{attrs:{"slot":"content","href":_vm.remoteSDPURL,"download":"remoteSDP.txt"},slot:"content"},[_vm._v("remoteSDP")])]):_vm._e(),(_vm.localSDP)?_c('mu-badge',[_c('a',{attrs:{"slot":"content","href":_vm.localSDPURL,"download":"localSDP.txt"},slot:"content"},[_vm._v("localSDP")])]):_vm._e()],1)])}
var Playervue_type_template_id_30c7d0b2_staticRenderFns = []
// CONCATENATED MODULE: ./src/components/Player.vue?vue&type=template&id=30c7d0b2&
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/Player.vue?vue&type=script&lang=js&
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
let pc = null;
/* harmony default export */ var Playervue_type_script_lang_js_ = ({
data() {
return {
iceConnectionState: pc && pc.iceConnectionState,
stream: null,
localSDP: "",
remoteSDP: "",
remoteSDPURL: "",
localSDPURL: "",
streamPath: ""
};
},
props:{
PublicIP:String
},
methods: {
async play(streamPath) {
pc = new RTCPeerConnection();
pc.addTransceiver('video',{
direction:'recvonly'
})
this.streamPath = streamPath;
pc.onsignalingstatechange = e => {
//console.log(e);
};
pc.oniceconnectionstatechange = e => {
this.$toast.info(pc.iceConnectionState);
this.iceConnectionState = pc.iceConnectionState;
};
pc.onicecandidate = event => {
console.log(event)
};
pc.ontrack = event => {
// console.log(event);
if (event.track.kind == "video")
this.stream = event.streams[0];
};
await pc.setLocalDescription(await pc.createOffer());
this.localSDP = pc.localDescription.sdp;
this.localSDPURL = URL.createObjectURL(
new Blob([this.localSDP], { type: "text/plain" })
);
const result = await this.ajax({
type: "POST",
processData: false,
data: JSON.stringify(pc.localDescription.toJSON()),
url: "/webrtc/play?streamPath=" + this.streamPath,
dataType: "json"
});
if (result.errmsg) {
this.$toast.error(result.errmsg);
return;
} else {
this.remoteSDP = result.sdp;
this.remoteSDPURL = URL.createObjectURL(new Blob([this.remoteSDP], { type: "text/plain" }));
}
await pc.setRemoteDescription(new RTCSessionDescription(result));
},
onClosePreview() {
pc.close();
}
}
});
// CONCATENATED MODULE: ./src/components/Player.vue?vue&type=script&lang=js&
/* harmony default export */ var components_Playervue_type_script_lang_js_ = (Playervue_type_script_lang_js_);
// CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
/* globals __VUE_SSR_CONTEXT__ */
// IMPORTANT: Do NOT use ES2015 features in this file (except for modules).
// This module is a runtime utility for cleaner component module output and will
// be included in the final webpack user bundle.
function normalizeComponent (
scriptExports,
render,
staticRenderFns,
functionalTemplate,
injectStyles,
scopeId,
moduleIdentifier, /* server only */
shadowMode /* vue-cli only */
) {
// Vue.extend constructor export interop
var options = typeof scriptExports === 'function'
? scriptExports.options
: scriptExports
// render functions
if (render) {
options.render = render
options.staticRenderFns = staticRenderFns
options._compiled = true
}
// functional template
if (functionalTemplate) {
options.functional = true
}
// scopedId
if (scopeId) {
options._scopeId = 'data-v-' + scopeId
}
var hook
if (moduleIdentifier) { // server build
hook = function (context) {
// 2.3 injection
context =
context || // cached call
(this.$vnode && this.$vnode.ssrContext) || // stateful
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional
// 2.2 with runInNewContext: true
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__
}
// inject component styles
if (injectStyles) {
injectStyles.call(this, context)
}
// register component module identifier for async chunk inferrence
if (context && context._registeredComponents) {
context._registeredComponents.add(moduleIdentifier)
}
}
// used by ssr in case component is cached and beforeCreate
// never gets called
options._ssrRegister = hook
} else if (injectStyles) {
hook = shadowMode
? function () {
injectStyles.call(
this,
(options.functional ? this.parent : this).$root.$options.shadowRoot
)
}
: injectStyles
}
if (hook) {
if (options.functional) {
// for template-only hot-reload because in that case the render fn doesn't
// go through the normalizer
options._injectStyles = hook
// register for functional component in vue file
var originalRender = options.render
options.render = function renderWithStyleInjection (h, context) {
hook.call(context)
return originalRender(h, context)
}
} else {
// inject component registration as beforeCreate hook
var existing = options.beforeCreate
options.beforeCreate = existing
? [].concat(existing, hook)
: [hook]
}
}
return {
exports: scriptExports,
options: options
}
}
// CONCATENATED MODULE: ./src/components/Player.vue
/* normalize component */
var component = normalizeComponent(
components_Playervue_type_script_lang_js_,
Playervue_type_template_id_30c7d0b2_render,
Playervue_type_template_id_30c7d0b2_staticRenderFns,
false,
null,
null,
null
)
/* harmony default export */ var Player = (component.exports);
// CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=script&lang=js&
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
const config = { iceServers: []};
let Appvue_type_script_lang_js_pc = new RTCPeerConnection(config);
var stream = null
var streamPath = "live/rtc";
/* harmony default export */ var Appvue_type_script_lang_js_ = ({
components:{
WebrtcPlayer: Player
},
props:{
PublicIP:String
},
data() {
return {
localSDP: Appvue_type_script_lang_js_pc && Appvue_type_script_lang_js_pc.localDescription && Appvue_type_script_lang_js_pc.localDescription.sdp,
remoteSDP: Appvue_type_script_lang_js_pc && Appvue_type_script_lang_js_pc.remoteDescription && Appvue_type_script_lang_js_pc.remoteDescription.sdp,
streamPath,
iceConnectionState: Appvue_type_script_lang_js_pc && Appvue_type_script_lang_js_pc.iceConnectionState,
stream,
previewStreamPath:false,
localSDPURL:"",
remoteSDPURL:""
};
},
methods: {
async publish() {
Appvue_type_script_lang_js_pc.addStream(stream);
await Appvue_type_script_lang_js_pc.setLocalDescription(await Appvue_type_script_lang_js_pc.createOffer());
this.localSDP = Appvue_type_script_lang_js_pc.localDescription.sdp;
this.localSDPURL = URL.createObjectURL(new Blob([ this.localSDP ],{type:'text/plain'}))
const result = await this.ajax({
type: "POST",
processData: false,
data: JSON.stringify(Appvue_type_script_lang_js_pc.localDescription),
url: "/webrtc/publish?streamPath=" + this.streamPath,
dataType: "json"
});
console.log(result)
if (typeof result == "string"){
this.$toast.error(result);
return;
}
streamPath = this.streamPath;
this.remoteSDP = result.sdp;
this.remoteSDPURL = URL.createObjectURL(new Blob([ this.remoteSDP ],{type:'text/plain'}))
Appvue_type_script_lang_js_pc.setRemoteDescription(new RTCSessionDescription(result));
},
stopSession() {
Appvue_type_script_lang_js_pc.close();
Appvue_type_script_lang_js_pc = new RTCPeerConnection(config);
this.remoteSDP = "";
this.localSDP = "";
// this.connectICE().catch(err => this.$toast.error(err.message));
},
preview({row}) {
this.previewStreamPath = true
this.$nextTick(() =>this.$refs.player.play(row.StreamPath));
},
},
async mounted() {
Appvue_type_script_lang_js_pc.onsignalingstatechange = e => {
console.log(e);
};
Appvue_type_script_lang_js_pc.oniceconnectionstatechange = e => {
this.$toast.info(Appvue_type_script_lang_js_pc.iceConnectionState);
this.iceConnectionState = Appvue_type_script_lang_js_pc.iceConnectionState;
};
Appvue_type_script_lang_js_pc.onicecandidate = event => {};
this.$parent.titleTabs = ["publish","play"];
try {
if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia(
{ video: true, audio: true }
);
} catch (err) {
this.$toast.error(err.message);
}
}
});
// CONCATENATED MODULE: ./src/App.vue?vue&type=script&lang=js&
/* harmony default export */ var src_Appvue_type_script_lang_js_ = (Appvue_type_script_lang_js_);
// EXTERNAL MODULE: ./src/App.vue?vue&type=style&index=0&id=674ea55a&scoped=true&lang=css&
var Appvue_type_style_index_0_id_674ea55a_scoped_true_lang_css_ = __webpack_require__("bce4");
// CONCATENATED MODULE: ./src/App.vue
/* normalize component */
var App_component = normalizeComponent(
src_Appvue_type_script_lang_js_,
render,
staticRenderFns,
false,
null,
"674ea55a",
null
)
/* harmony default export */ var App = (App_component.exports);
// CONCATENATED MODULE: ./node_modules/@vue/cli-service/lib/commands/build/entry-lib.js
/* harmony default export */ var entry_lib = __webpack_exports__["default"] = (App);
/***/ })
/******/ })["default"];
});
//# sourceMappingURL=plugin-webrtc.umd.js.map

1
ui/dist/plugin-webrtc.umd.js.map

File diff suppressed because one or more lines are too long

2
ui/dist/plugin-webrtc.umd.min.js

File diff suppressed because one or more lines are too long

1
ui/dist/plugin-webrtc.umd.min.js.map

File diff suppressed because one or more lines are too long

9392
ui/package-lock.json

File diff suppressed because it is too large

15
ui/package.json

@ -1,15 +0,0 @@
{
"name": "dashboard",
"version": "1.0.0",
"description": "dashboard of webrtc plugin for monibuca",
"main": "index.js",
"scripts": {
"build": "vue-cli-service build --target lib --name plugin-webrtc"
},
"author": "dexter",
"license": "ISC",
"devDependencies": {
"@vue/cli-service": "^4.2.3",
"vue-template-compiler": "^2.6.11"
}
}

124
ui/src/App.vue

@ -1,124 +0,0 @@
<template>
<div>
<div v-if="$parent.titleTabActive == 0">
<mu-text-field v-model="streamPath" label="streamPath"></mu-text-field>
<m-button @click="publish" v-if="!remoteSDP">Publish</m-button>
<m-button @click="stopSession" v-else>Stop</m-button>
<mu-badge v-if="remoteSDP">
<a slot="content" :href="remoteSDPURL" download="remoteSDP.txt">remoteSDP</a>
</mu-badge>
<mu-badge v-if="localSDP">
<a slot="content" :href="localSDPURL" download="localSDP.txt">localSDP</a>
</mu-badge>
<br />
<video ref="video1" :srcObject.prop="stream" width="640" height="480" autoplay muted></video>
</div>
<stream-table v-else-if="$parent.titleTabActive == 1">
<template v-slot="scope">
<m-button @click="preview(scope)">Play</m-button>
<template>
</stream-table>
<pre v-else-if="$parent.titleTabActive == 2">{{localSDP}}</pre>
<pre v-else-if="$parent.titleTabActive == 3">{{remoteSDP}}</pre>
<webrtc-player ref="player" v-model="previewStreamPath" :PublicIP="PublicIP"></webrtc-player>
</div>
</template>
<script>
import WebrtcPlayer from "./components/Player"
const config = { iceServers: []};
let pc = new RTCPeerConnection(config);
var stream = null
var streamPath = "live/rtc";
export default {
components:{
WebrtcPlayer
},
props:{
PublicIP:String
},
data() {
return {
localSDP: pc && pc.localDescription && pc.localDescription.sdp,
remoteSDP: pc && pc.remoteDescription && pc.remoteDescription.sdp,
streamPath,
iceConnectionState: pc && pc.iceConnectionState,
stream,
previewStreamPath:false,
localSDPURL:"",
remoteSDPURL:""
};
},
methods: {
async publish() {
pc.addStream(stream);
await pc.setLocalDescription(await pc.createOffer());
this.localSDP = pc.localDescription.sdp;
this.localSDPURL = URL.createObjectURL(new Blob([ this.localSDP ],{type:'text/plain'}))
const result = await this.ajax({
type: "POST",
processData: false,
data: JSON.stringify(pc.localDescription),
url: "/webrtc/publish?streamPath=" + this.streamPath,
dataType: "json"
});
console.log(result)
if (typeof result == "string"){
this.$toast.error(result);
return;
}
streamPath = this.streamPath;
this.remoteSDP = result.sdp;
this.remoteSDPURL = URL.createObjectURL(new Blob([ this.remoteSDP ],{type:'text/plain'}))
pc.setRemoteDescription(new RTCSessionDescription(result));
},
stopSession() {
pc.close();
pc = new RTCPeerConnection(config);
this.remoteSDP = "";
this.localSDP = "";
// this.connectICE().catch(err => this.$toast.error(err.message));
},
preview({row}) {
this.previewStreamPath = true
this.$nextTick(() =>this.$refs.player.play(row.StreamPath));
},
},
async mounted() {
pc.onsignalingstatechange = e => {
console.log(e);
};
pc.oniceconnectionstatechange = e => {
this.$toast.info(pc.iceConnectionState);
this.iceConnectionState = pc.iceConnectionState;
};
pc.onicecandidate = event => {};
this.$parent.titleTabs = ["publish","play"];
try {
if (!this.stream)
this.stream = stream = await navigator.mediaDevices.getUserMedia(
{ video: true, audio: true }
);
} catch (err) {
this.$toast.error(err.message);
}
}
};
</script>
<style scoped>
@keyframes blink {
0% {
opacity: 0.2;
}
50% {
opacity: 1;
}
100% {
opacity: 0.2;
}
}
.blink {
animation: blink 1s infinite;
}
</style>

86
ui/src/components/Player.vue

@ -1,86 +0,0 @@
<template>
<Modal
v-bind="$attrs"
draggable
v-on="$listeners"
:title="streamPath"
@on-ok="onClosePreview"
@on-cancel="onClosePreview"
>
<video ref="webrtc" :srcObject.prop="stream" width="488" height="275" autoplay muted controls></video>
<div slot="footer">
<mu-badge v-if="remoteSDP">
<a slot="content" :href="remoteSDPURL" download="remoteSDP.txt">remoteSDP</a>
</mu-badge>
<mu-badge v-if="localSDP">
<a slot="content" :href="localSDPURL" download="localSDP.txt">localSDP</a>
</mu-badge>
</div>
</Modal>
</template>
<script>
let pc = null;
export default {
data() {
return {
iceConnectionState: pc && pc.iceConnectionState,
stream: null,
localSDP: "",
remoteSDP: "",
remoteSDPURL: "",
localSDPURL: "",
streamPath: ""
};
},
props:{
PublicIP:String
},
methods: {
async play(streamPath) {
pc = new RTCPeerConnection();
pc.addTransceiver('video',{
direction:'recvonly'
})
this.streamPath = streamPath;
pc.onsignalingstatechange = e => {
//console.log(e);
};
pc.oniceconnectionstatechange = e => {
this.$toast.info(pc.iceConnectionState);
this.iceConnectionState = pc.iceConnectionState;
};
pc.onicecandidate = event => {
console.log(event)
};
pc.ontrack = event => {
// console.log(event);
if (event.track.kind == "video")
this.stream = event.streams[0];
};
await pc.setLocalDescription(await pc.createOffer());
this.localSDP = pc.localDescription.sdp;
this.localSDPURL = URL.createObjectURL(
new Blob([this.localSDP], { type: "text/plain" })
);
const result = await this.ajax({
type: "POST",
processData: false,
data: JSON.stringify(pc.localDescription.toJSON()),
url: "/webrtc/play?streamPath=" + this.streamPath,
dataType: "json"
});
if (result.errmsg) {
this.$toast.error(result.errmsg);
return;
} else {
this.remoteSDP = result.sdp;
this.remoteSDPURL = URL.createObjectURL(new Blob([this.remoteSDP], { type: "text/plain" }));
}
await pc.setRemoteDescription(new RTCSessionDescription(result));
},
onClosePreview() {
pc.close();
}
}
};
</script>
Loading…
Cancel
Save