从文
This commit is contained in:
TimSpan 2024-08-05 16:43:08 +08:00
parent 01097b26d9
commit 67af89c969
107 changed files with 16798 additions and 44 deletions

1
components.d.ts vendored
View File

@ -10,6 +10,7 @@ declare module 'vue' {
404: typeof import('./src/components/errorMessage/404.vue')['default']
500: typeof import('./src/components/errorMessage/500.vue')['default']
AButton: typeof import('ant-design-vue/es')['Button']
ACascader: typeof import('ant-design-vue/es')['Cascader']
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
AForm: typeof import('ant-design-vue/es')['Form']

View File

@ -16,8 +16,31 @@
<script src="/haikang/h5player.min.js"></script>
<!-- <script src=" ./public/cw/player/cmsplayer.js"></script>
<script src=" ./public/cw/player/common.js"></script>
<script src=" ./public/cw/player/pcm-player.js"></script>
<script src=" ./public/cw/player/webgl.js"></script>
<script src=" ./public/cw/player/cmstalk.js"></script>
<script src=" ./public/cw/player/alawmulaw.js"></script>
<script src=" ./public/cw/player/recorder-core.js"></script>
<script src=" ./public/cw/js/moment.js"></script>
<script src=" ./public/cw/js/jquery-3.4.1.min.js"></script> -->
<script src="/cw/js/moment.js"></script>
<script src="/cw/js/jquery-2.2.3.min.js"></script>
<script src="/cw/player/cmsplayer.js"></script>
<script src="/cw/player/common.js"></script>
<script src="/cw/player/pcm-player.js"></script>
<script src="/cw/player/webgl.js"></script>
<script src="/cw/player/cmstalk.js"></script>
<script src="/cw/player/alawmulaw.js"></script>
<script src="/cw/player/recorder-core.js"></script>
<script type="module" src="/src/main.ts">
</script>
</body>

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/cw/help/Thumbs.db Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 KiB

BIN
public/cw/images/arrow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

View File

@ -0,0 +1 @@
<svg t="1665647640241" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4863" width="32" height="32"><path d="M512 422.4c-70.4 0-128 57.6-128 128s57.6 128 128 128 128-57.6 128-128-57.6-128-128-128z" p-id="4864" fill="#ffffff"></path><path d="M940.8 198.4h-208V144c0-19.2-16-38.4-38.4-38.4h-368c-19.2 0-38.4 16-38.4 38.4v54.4H80c-28.8 0-51.2 22.4-51.2 51.2v620.8c0 28.8 22.4 51.2 51.2 51.2h860.8c28.8 0 51.2-22.4 51.2-51.2V249.6c0-28.8-22.4-51.2-51.2-51.2zM512 771.2c-121.6 0-220.8-99.2-220.8-220.8 0-121.6 99.2-220.8 220.8-220.8s220.8 99.2 220.8 220.8c0 121.6-99.2 220.8-220.8 220.8z m368-460.8H732.8v-35.2H880v35.2z" p-id="4865" fill="#ffffff"></path></svg>

After

Width:  |  Height:  |  Size: 702 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1646746198883" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3880" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M820.053333 205.077333a42.666667 42.666667 0 0 1 1.408 57.664l-2.538666 2.666667L562.837333 512l256.085334 246.613333a42.666667 42.666667 0 0 1-56.426667 63.893334l-2.773333-2.432L501.333333 571.221333 242.922667 820.074667a42.666667 42.666667 0 0 1-61.717334-58.816l2.538667-2.666667L439.808 512 183.744 265.386667a42.666667 42.666667 0 0 1 56.426667-63.893334l2.773333 2.432 258.368 248.832L759.744 203.925333a42.666667 42.666667 0 0 1 60.330667 1.152z" p-id="3881" fill="#ffffff"></path></svg>

After

Width:  |  Height:  |  Size: 871 B

View File

@ -0,0 +1 @@
<svg t="1665649555889" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2290" width="32" height="32"><path d="M511.883031 56.77603c-250.925838 0-455.090006 204.166167-455.090006 455.092005v244.611503c0 108.255456 88.059781 196.257252 196.258252 196.257252 80.037896 0 145.061751-65.020856 145.061752-145.002767V642.706536c0-79.978912-65.021856-145.061751-145.061752-145.061751a195.335496 195.335496 0 0 0-110.92975 34.643865v-20.417616c0-203.881242 165.881262-369.762504 369.760504-369.762504s369.760505 165.881262 369.760505 369.762504v20.421615a195.059568 195.059568 0 0 0-110.927752-34.643865c-79.978912 0-145.061751 65.082839-145.061751 145.061751v165.023488c0 79.978912 65.082839 145.002767 145.061751 145.002767 108.197471 0 196.258252-88.001796 196.258252-196.257252V511.871034c0.001-250.933836-204.164168-455.095004-455.090005-455.095004zM253.051277 582.976286a59.759243 59.759243 0 0 1 59.729252 59.73025v165.027487a59.711256 59.711256 0 0 1-59.729252 59.673266A111.070714 111.070714 0 0 1 142.121527 756.479538v-62.518516a111.08371 111.08371 0 0 1 110.92975-110.985736z m628.592258 173.503252A111.070714 111.070714 0 0 1 770.715784 867.408289a59.748246 59.748246 0 0 1-59.730251-59.673266V642.706536A59.796233 59.796233 0 0 1 770.715784 582.976286a111.082711 111.082711 0 0 1 110.927751 110.985736v62.518515z" p-id="2291" fill="#ffffff"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1646745129934" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1383" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M768 298.666667h170.666667v85.333333h-256V128h85.333333v170.666667zM341.333333 384H85.333333V298.666667h170.666667V128h85.333333v256z m426.666667 341.333333v170.666667h-85.333333v-256h256v85.333333h-170.666667zM341.333333 640v256H256v-170.666667H85.333333v-85.333333h256z" p-id="1384" fill="#ffffff"></path></svg>

After

Width:  |  Height:  |  Size: 688 B

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M18,32V52a4.012,4.012,0,0,0,4,4H62a4.012,4.012,0,0,0,4-4V32a4.012,4.012,0,0,0-4-4H22A4.012,4.012,0,0,0,18,32Zm6,2H60V50H24ZM7,36a3,3,0,0,0,3-3V23a3,3,0,0,1,3-3H23a3,3,0,0,0,0-6H13a9.01,9.01,0,0,0-9,9V33A3,3,0,0,0,7,36ZM71,14H61a3,3,0,0,0,0,6H71a3,3,0,0,1,3,3V33a3,3,0,0,0,6,0V23A9.01,9.01,0,0,0,71,14Zm6,34a3,3,0,0,0-3,3V61a3,3,0,0,1-3,3H61a3,3,0,0,0,0,6H71a9.01,9.01,0,0,0,9-9V51A3,3,0,0,0,77,48ZM23,64H13a3,3,0,0,1-3-3V51a3,3,0,0,0-6,0V61a9.01,9.01,0,0,0,9,9H23a3,3,0,0,0,0-6Z"/></svg>

After

Width:  |  Height:  |  Size: 682 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1646745119141" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1430" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M213.333333 213.333333h213.333334V128H170.666667a42.666667 42.666667 0 0 0-42.666667 42.666667v256h85.333333V213.333333zM170.666667 896h256v-85.333333H213.333333v-213.333334H128v256a42.666667 42.666667 0 0 0 42.666667 42.666667z m725.333333-42.666667v-256h-85.333333v213.333334h-213.333334v85.333333h256a42.666667 42.666667 0 0 0 42.666667-42.666667zM597.333333 213.333333h213.333334v213.333334h85.333333V170.666667a42.666667 42.666667 0 0 0-42.666667-42.666667h-256v85.333333z" fill="#ffffff" p-id="1431"></path></svg>

After

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<title>视频操作</title>
<g>
<path class="st0" d="M49.3,42.2c1.8-3,2.7-6.4,2.7-10.2v-4.6c0-0.6-0.2-1.2-0.7-1.6s-1-0.7-1.6-0.7s-1.2,0.2-1.6,0.7
s-0.7,1-0.7,1.6V32c0,2.5-0.5,4.7-1.5,6.8L49.3,42.2z"/>
<path class="st0" d="M31,43.5c1.7,0,3.2-0.3,4.6-0.9L19.3,26.4V32c0,3.2,1.1,5.9,3.4,8.2S27.8,43.5,31,43.5z"/>
<path class="st0" d="M42.7,57.4h-9.3v-4.8c3.4-0.4,6.4-1.4,9.1-3.2L39,46.1c-2.4,1.4-5.1,2.1-8,2.1c-4.5,0-8.3-1.6-11.5-4.7
c-3.2-3.2-4.8-7-4.8-11.4v-4.6c0-0.6-0.2-1.2-0.7-1.6c-0.5-0.5-1-0.7-1.6-0.7s-1.2,0.2-1.6,0.7c-0.5,0.5-0.7,1-0.7,1.6V32
c0,5.3,1.8,9.9,5.4,13.9c3.6,3.9,8,6.2,13.3,6.8v4.8h-9.3c-0.6,0-1.2,0.2-1.6,0.7s-0.7,1-0.7,1.6s0.2,1.2,0.7,1.6s1,0.7,1.6,0.7
h23.3c0.6,0,1.2-0.2,1.6-0.7s0.7-1,0.7-1.6s-0.2-1.2-0.7-1.6S43.3,57.4,42.7,57.4z"/>
<path class="st0" d="M42.2,35.2c0.3-1,0.4-2.1,0.4-3.2V13.5c0-3.2-1.1-5.9-3.4-8.2S34.2,2,31,2s-6,1.1-8.2,3.4c-2,2-3.1,4.3-3.4,7
L42.2,35.2z"/>
</g>
<path class="st0" d="M50.9,55.1l-42-42c-1.2-1.2-1.2-3,0-4.2l0,0c1.2-1.2,3-1.2,4.2,0L55.2,51c1.2,1.2,1.2,3,0,4.2l0,0
C54,56.3,52.1,56.3,50.9,55.1z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<title>视频操作</title>
<path class="st0" d="M52,27.4V32c0,5.3-1.8,9.9-5.4,13.9s-8,6.2-13.3,6.8v4.8h9.3c0.6,0,1.2,0.2,1.6,0.7c0.5,0.5,0.7,1,0.7,1.6
s-0.2,1.2-0.7,1.6c-0.5,0.5-1,0.7-1.6,0.7H19.3c-0.6,0-1.2-0.2-1.6-0.7c-0.5-0.5-0.7-1-0.7-1.6s0.2-1.2,0.7-1.6
c0.5-0.5,1-0.7,1.6-0.7h9.3v-4.8c-5.3-0.6-9.7-2.8-13.3-6.8c-3.5-4-5.3-8.6-5.3-13.9v-4.6c0-0.6,0.2-1.2,0.7-1.6
c0.5-0.5,1-0.7,1.6-0.7s1.2,0.2,1.6,0.7c0.5,0.5,0.7,1,0.7,1.6V32c0,4.4,1.6,8.3,4.8,11.4c3.2,3.2,7,4.7,11.5,4.7s8.3-1.6,11.5-4.7
c3.2-3.2,4.8-7,4.8-11.4v-4.6c0-0.6,0.2-1.2,0.7-1.6c0.5-0.5,1-0.7,1.6-0.7s1.2,0.2,1.6,0.7C51.8,26.2,52,26.8,52,27.4z M42.7,13.5
V32c0,3.2-1.1,5.9-3.4,8.2c-2.3,2.3-5,3.4-8.2,3.4s-6-1.1-8.2-3.4s-3.4-5-3.4-8.2V13.5c0-3.2,1.1-5.9,3.4-8.2S27.8,2,31,2
s6,1.1,8.2,3.4S42.7,10.4,42.7,13.5z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M44.269,12a4.385,4.385,0,0,0-2.5.816L23.264,27.05H16.71A7.625,7.625,0,0,0,9,34.542V49.525a7.625,7.625,0,0,0,7.71,7.491h6.554l18.5,14.234a3.387,3.387,0,0,0,2.161.75,3.96,3.96,0,0,0,4.007-3.746V15.813A3.625,3.625,0,0,0,44.269,12ZM41.936,61.779a1,1,0,0,1-1.61.792L26.922,52.26,25.3,51.016H16.71A1.634,1.634,0,0,1,15,49.525V34.542a1.634,1.634,0,0,1,1.71-1.492H25.3l1.618-1.244L40.326,21.5a1,1,0,0,1,1.61.792ZM67.78,42.845,74.125,36.5a3,3,0,0,0-4.243-4.243L63.537,38.6l-6.345-6.345A3,3,0,0,0,52.95,36.5L59.3,42.845,52.95,49.19a3,3,0,1,0,4.242,4.242l6.345-6.345,6.345,6.345a3.009,3.009,0,0,0,4.243,0h0a3.008,3.008,0,0,0,0-4.242Z"/></svg>

After

Width:  |  Height:  |  Size: 826 B

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M27,18a3.009,3.009,0,0,0-3,3V63a3,3,0,0,0,6,0V21A3.009,3.009,0,0,0,27,18Zm30,0a3.009,3.009,0,0,0-3,3V63a3,3,0,0,0,6,0V21A3.009,3.009,0,0,0,57,18Z"/></svg>

After

Width:  |  Height:  |  Size: 349 B

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M66,15H18A12.035,12.035,0,0,0,6,27V57A12.035,12.035,0,0,0,18,69H66A12.035,12.035,0,0,0,78,57V27A12.035,12.035,0,0,0,66,15Zm6,42a6.007,6.007,0,0,1-6,6H18a6.011,6.011,0,0,1-5.877-4.787l12.934-11.3a3.051,3.051,0,0,1,.976-.476,1.315,1.315,0,0,1,.319-.046.8.8,0,0,1,.595.308c2.918,2.919,6.069,6.484,6.186,6.616a5.184,5.184,0,0,0,3.538,1.855c.1.007.209.011.32.011a5.27,5.27,0,0,0,3.749-1.655c.675-.649,10.811-10.129,14.608-13.666l.115-.116a3.742,3.742,0,0,1,2.235-1.06,2.742,2.742,0,0,1,1.877,1.04C62.048,42.329,68.2,51.055,72,56.7Zm0-10.483a96.045,96.045,0,0,0-8.045-10.945,8.538,8.538,0,0,0-6.27-2.922,9.745,9.745,0,0,0-6.5,2.834c-.885.823-11.464,10.7-14.107,13.2-1.888-2.115-3.856-4.212-5.854-6.238a6.787,6.787,0,0,0-6.953-1.777A8.755,8.755,0,0,0,21.313,42.2l-.056.035L12,50.219V27a6.007,6.007,0,0,1,6-6H66a6.007,6.007,0,0,1,6,6ZM25,26a4,4,0,1,0,4,4A4,4,0,0,0,25,26Z"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M27,22.264,55.5,42,27,61.736V22.264M25.565,15A4.394,4.394,0,0,0,21,19.211V64.789A4.394,4.394,0,0,0,25.565,69a4.722,4.722,0,0,0,2.707-.847L61.179,45.364a4.018,4.018,0,0,0,0-6.728L28.272,15.847A4.722,4.722,0,0,0,25.565,15Z"/></svg>

After

Width:  |  Height:  |  Size: 424 B

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M73.4,40.52a3.12,3.12,0,0,0-3.138,3.094v.922a17.223,17.223,0,0,1-17.23,17.178H19.262v-6.7a.4.4,0,0,0-.239-.361.433.433,0,0,0-.46.064l-11.424,9.8a.388.388,0,0,0,0,.594L18.565,74.9a.429.429,0,0,0,.279.1.434.434,0,0,0,.179-.039.4.4,0,0,0,.239-.356v-6.7h33.77a23.463,23.463,0,0,0,23.5-23.371v-.922A3.118,3.118,0,0,0,73.4,40.52Zm3.462-21.626L65.435,9.1a.433.433,0,0,0-.279-.1.438.438,0,0,0-.178.038.4.4,0,0,0-.239.354v6.7H30.968a23.463,23.463,0,0,0-23.5,23.371v.921a3.135,3.135,0,0,0,6.269,0v-.921a17.225,17.225,0,0,1,17.23-17.179H64.739v6.7a.4.4,0,0,0,.241.36.415.415,0,0,0,.177.039.428.428,0,0,0,.277-.1l11.425-9.8a.4.4,0,0,0,.141-.3A.393.393,0,0,0,76.862,18.894ZM33.607,38.067a3.151,3.151,0,0,1-1.3-.281l-3.715-1.664-.49,4.041A14.237,14.237,0,1,0,42.229,27.727a14.3,14.3,0,0,0-4.677.783l-3.9,1.347,2.484,3.3a3.023,3.023,0,0,1,.618,1.827A3.121,3.121,0,0,1,33.607,38.067Zm9.147-3.088a8.973,8.973,0,0,0-.085-1.241,8.128,8.128,0,1,1-8.368,10.3A9.125,9.125,0,0,0,42.754,34.979Z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M59.818,17.687a2.887,2.887,0,0,0-3.936,1.092A3.1,3.1,0,0,0,57.287,22.6,20.827,20.827,0,0,1,69.1,42.273a20.949,20.949,0,0,1-12.09,19.4,2.382,2.382,0,0,0-1.124,3.552,2.887,2.887,0,0,0,3.936,1.092,27.059,27.059,0,0,0,0-48.626Zm3.374,24.257a15.4,15.4,0,0,0-5.624-12.02,3.078,3.078,0,0,0-3.936.273,2.587,2.587,0,0,0,0,3.825,10.5,10.5,0,0,1,0,16.391c-1.124.819-1.124,2.732,0,3.278a2.77,2.77,0,0,0,3.936.273A15.4,15.4,0,0,0,63.192,41.944ZM44.269,12a4.385,4.385,0,0,0-2.5.816L23.264,27.05H16.71A7.625,7.625,0,0,0,9,34.542V49.525a7.625,7.625,0,0,0,7.71,7.491h6.554l18.5,14.234a3.387,3.387,0,0,0,2.161.75,3.96,3.96,0,0,0,4.007-3.746V15.813A3.625,3.625,0,0,0,44.269,12ZM41.936,61.779a1,1,0,0,1-1.61.792L26.922,52.26,25.3,51.016H16.71A1.634,1.634,0,0,1,15,49.525V34.542a1.634,1.634,0,0,1,1.71-1.492H25.3l1.618-1.244L40.326,21.5a1,1,0,0,1,1.61.792Z"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

4
public/cw/js/jquery-2.2.3.min.js vendored Normal file

File diff suppressed because one or more lines are too long

4602
public/cw/js/moment.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
(function(d,e){"object"===typeof exports&&"undefined"!==typeof module?e(exports):"function"===typeof define&&define.amd?define(["exports"],e):(d=d||self,e(d.alawmulaw={}))})(this,function(d){function e(a){a=-32768==a?-32767:a;var c=~a>>8&128;c||(a*=-1);32635<a&&(a=32635);if(256<=a){var b=k[a>>8&127];a=b<<4|a>>b+3&15}else a>>=4;return a^c^85}function f(a){var c=0;a^=85;a&128&&(a&=-129,c=-1);var b=((a&240)>>4)+4;a=4!=b?1<<b|(a&15)<<b-4|1<<b-5:a<<1|1;return-8*(0===c?a:-a)}function g(a){var c=a>>8&128;
0!=c&&(a=-a);a+=132;32635<a&&(a=32635);var b=l[a>>7&255];return~(c|b<<4|a>>b+3&15)}function h(a){a=~a;var c=a>>4&7;c=m[c]+((a&15)<<c+3);0!=(a&128)&&(c=-c);return c}var k=[1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7],n=Object.freeze({__proto__:null,encodeSample:e,decodeSample:f,encode:function(a){for(var c=
new Uint8Array(a.length),b=0;b<a.length;b++)c[b]=e(a[b]);return c},decode:function(a){for(var c=new Int16Array(a.length),b=0;b<a.length;b++)c[b]=f(a[b]);return c}}),l=[0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7],m=[0,132,396,924,1980,4092,8316,16764],p=Object.freeze({__proto__:null,encodeSample:g,decodeSample:h,encode:function(a){for(var c=new Uint8Array(a.length),b=0;b<a.length;b++)c[b]=g(a[b]);return c},decode:function(a){for(var c=new Int16Array(a.length),b=0;b<a.length;b++)c[b]=h(a[b]);return c}});d.alaw=n;d.mulaw=p;Object.defineProperty(d,
"__esModule",{value:!0})});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

234
public/cw/player/cmstalk.js Normal file
View File

@ -0,0 +1,234 @@
function CmsTalk() {
this.wasmLoaded = false;
this.logger = new Logger("CmsTalk");
this.urlBufferBuffer = null
this.audioCache = null
this.localAudioStream = null
this.ws = null
this.mediaRecorder = null
this.audioBuffer = null
this.rec = null
// this.recBlob = null;
/**调用open打开录音请求好录音权限**/
this.RecorderOpen()
}
CmsTalk.prototype.RecorderOpen = function () {
//recOpen我们可以选择性的弹一个对话框为了防止移动端浏览器存在第三种情况用户忽略并且或者国产系统UC系浏览器没有任何回调
var showDialog = function () {
if (!/mobile/i.test(navigator.userAgent)) {
return //只在移动端开启没有权限请求的检测
}
dialogCancel()
//显示弹框,应该使用自己的弹框方式
var div = document.createElement("div")
document.body.appendChild(div)
div.innerHTML =
"" +
'<div class="waitDialog" style="z-index:99999;width:100%;height:100%;top:0;left:0;position:fixed;background:rgba(0,0,0,0.3);">' +
'<div style="display:flex;height:100%;align-items:center;">' +
'<div style="flex:1;"></div>' +
'<div style="width:240px;background:#fff;padding:15px 20px;border-radius: 10px;">' +
'<div style="padding-bottom:10px;">录音功能需要麦克风权限,请允许;如果未看到任何请求,请点击忽略~</div>' +
'<div style="text-align:center;"><a onclick="waitDialogClick()" style="color:#0B1">忽略</a></div>' +
"</div>" +
'<div style="flex:1;"></div>' +
"</div>" +
"</div>"
}
var createDelayDialog = function () {
dialogInt = setTimeout(function () {
//定时8秒后打开弹窗用于监测浏览器没有发起权限请求的情况在open前放置定时器利于收到了回调能及时取消不管open是同步还是异步回调的
showDialog()
}, 8000)
}
var dialogInt
var dialogCancel = function () {
clearTimeout(dialogInt)
//关闭弹框,应该使用自己的弹框方式
var elems = document.querySelectorAll(".waitDialog")
for (var i = 0; i < elems.length; i++) {
elems[i].parentNode.removeChild(elems[i])
}
}
//recOpen弹框End
var formatMs = function (ms, all) {
var f = Math.floor(ms / 60000),
m = Math.floor(ms / 1000) % 60
var s =
(all || f > 0 ? (f < 10 ? "0" : "") + f + ":" : "") +
(all || f > 0 || m > 0 ? ("0" + m).substr(-2) + "″" : "") +
("00" + (ms % 1000)).substr(-3)
return s
}
// var recOpen = function () {//一般在显示出录音按钮或相关的录音界面时进行此方法调用,后面用户点击开始录音时就能畅通无阻了
this.newRec = Recorder({
type: "pcm", sampleRate: 8000, bitRate: 16 //mp3格式指定采样率hz、比特率kbps其他参数使用默认配置注意是数字的参数必须提供数字不要用字符串需要使用的type类型需提前把格式支持文件加载进来比如使用wav格式需要提前加载wav.js编码引擎
, onProcess: function (buffers, powerLevel, bufferDuration, bufferSampleRate, newBufferIdx, asyncEnd) {
newBufferIdx = 0
var newChunkInfo = Recorder.SampleData(buffers, 48000, 8000, this.prevChunkInfo);
this.sendAudioData(newChunkInfo.data)
this.prevChunkInfo = newChunkInfo
for (let index = buffers.length - 1; index >= 0; index--) {
buffers[index] = null;
}
}.bind(this)
});
// createDelayDialog(); //我们可以选择性的弹一个对话框为了防止移动端浏览器存在第三种情况用户忽略并且或者国产系统UC系浏览器没有任何回调此处demo省略了弹窗的代码
window.waitDialogClick = function () {
dialogCancel();
console.log("打开失败:权限请求被忽略,<span style='color:#f00'>用户主动点击的弹窗</span>", 1);
};
// };
}
//打开麦克风授权获得相关资源
CmsTalk.prototype.open = function (callback) {
// dialogCancel(); //如果开启了弹框,此处需要取消
if (this.rec){
console.log("已打开录音设备,可以点击录制开始录音了", 2);
callback(null)
return
}
this.newRec.open(function () {
this.rec = this.newRec;
console.log("已打开录音设备,可以点击录制开始录音了", 2);
callback()
}.bind(this), function (msg, isUserNotAllow) {
//用户拒绝未授权或不支持
// dialogCancel(); //如果开启了弹框,此处需要取消
var log = (isUserNotAllow ? "UserNotAllow" : "") + "打开录音失败:" + msg;
console.log(log);
callback(log)
})
}
/**关闭录音,释放资源**/
CmsTalk.prototype.recClose = function () {
if (this.rec) {
this.rec.close();
this.rec = null
console.log("已关闭");
} else {
console.log("未打开录音", 1);
};
};
/**开始录音**/
CmsTalk.prototype.recStart = function () {//打开了录音后才能进行start、stop调用
this.prevChunkInfo = null
if (this.rec && Recorder.IsOpen()) {
// this.recBlob = null;
this.rec.start();
console.log("已开始录音...");
} else {
console.log("未打开录音", 1);
};
};
/**暂停录音**/
CmsTalk.prototype.recPause = function () {
if (this.rec && Recorder.IsOpen()) {
this.rec.pause();
} else {
console.log("未打开录音", 1);
};
};
/**恢复录音**/
CmsTalk.prototype.recResume = function () {
if (this.rec && Recorder.IsOpen()) {
this.rec.resume();
} else {
console.log("未打开录音", 1);
};
};
/**结束录音,得到音频文件**/
CmsTalk.prototype.recStop = function () {
if (!(this.rec && Recorder.IsOpen())) {
console.log("未打开录音", 1);
return;
};
this.rec.stop(null, null);
};
CmsTalk.prototype.startTalk = function (url, callback) {
this.open((err) => {
if (err) {
callback(err)
} else {
if (url.indexOf("http") != -1) {
//方式1,可手动修改talk-server对应的地址
this.ws = new WebSocket("ws://192.168.0.215:3000");
this.ws.onmessage = function (msg) {
console.log(msg);
};
this.ws.onopen = (ev) => {
console.log("open")
this.ws.send(url)
this.recStart()
if (callback)
callback(null)
}
}
else {
//方式2
this.ws = new WebSocket(url);
this.ws.onmessage = function (msg) {
console.log(msg);
};
this.ws.onopen = (ev) => {
console.log("open")
this.recStart()
if (callback)
callback(null)
}
}
}
})
}
CmsTalk.prototype.stopTalk = function () {
if (this.ws) {
this.ws.close();
this.ws = null
}
if (this.audioBuffer) {
delete this.audioBuffer
this.audioBuffer = null
}
this.recStop()
// this.recClose()
}
CmsTalk.prototype.sendAudioData = function (samples) {
var u8Data = alawmulaw.alaw.encode(samples);
if (!this.audioBuffer)
this.audioBuffer = new Uint8Array([])
var tmpBuffer = new Uint8Array(this.audioBuffer.byteLength + u8Data.byteLength)
tmpBuffer.set(this.audioBuffer, 0)
tmpBuffer.set(u8Data, this.audioBuffer.byteLength)
while (tmpBuffer.byteLength >= 480) {
var d480 = tmpBuffer.subarray(0, 480);
tmpBuffer = tmpBuffer.subarray(480);
console.log("reserve ", tmpBuffer.length)
if (this.ws)
this.ws.send(d480)
}
this.audioBuffer = tmpBuffer
}

View File

@ -0,0 +1,51 @@
//Player request.
const kCloseDecoderReq = 0;
const kOpenDecoderReq = 1;
const kRequestHeaderReq = 2;
const kRequestBodyReq = 3;
const kPauseGetUrlReq = 4;
const kResumeGetUrlReq = 5;
const kRequestLiveReq = 6;
const kDecodeVideo = 7;
//CMSParser response.
const kCMSHeaderRes = 8;
const kVideoFrame = 9;
const kAudioFrame = 10;
const kImageFrame = 11;
const kFinishDownload = 12;
const kVideoBuffer = 13;
const kCmsPartHeader = 14;
function Logger(module) {
this.module = module;
}
Logger.prototype.log = function (line) {
console.log("[" + this.currentTimeStr() + "][" + this.module + "]" + line);
}
Logger.prototype.logError = function (line) {
// console.log("[" + this.currentTimeStr() + "][" + this.module + "][ER] " + line);
}
Logger.prototype.logInfo = function (line) {
// console.log("[" + this.currentTimeStr() + "][" + this.module + "][IF] " + line);
}
Logger.prototype.logDebug = function (line) {
// console.log("[" + this.currentTimeStr() + "][" + this.module + "][DT] " + line);
}
Logger.prototype.currentTimeStr = function () {
var now = new Date(Date.now());
var year = now.getFullYear();
var month = now.getMonth() + 1;
var day = now.getDate();
var hour = now.getHours();
var min = now.getMinutes();
var sec = now.getSeconds();
var ms = now.getMilliseconds();
return year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec + ":" + ms;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,14 @@
prefix=/home/weixin/player3/ffmpeg/../WasmVideoPlayer-master/dist
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: libavcodec
Description: FFmpeg codec library
Version: 57.89.100
Requires: libavutil >= 55.58.100
Requires.private:
Conflicts:
Libs: -L${libdir} -lavcodec -s USE_SDL=2 -lm -pthreads
Libs.private:
Cflags: -I${includedir}

View File

@ -0,0 +1,14 @@
prefix=/home/weixin/player3/ffmpeg/../WasmVideoPlayer-master/dist
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: libavformat
Description: FFmpeg container format library
Version: 57.71.100
Requires: libavcodec >= 57.89.100, libavutil >= 55.58.100
Requires.private:
Conflicts:
Libs: -L${libdir} -lavformat -s USE_SDL=2 -lm -pthreads
Libs.private:
Cflags: -I${includedir}

View File

@ -0,0 +1,14 @@
prefix=/home/weixin/player3/ffmpeg/../WasmVideoPlayer-master/dist
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: libavutil
Description: FFmpeg utility library
Version: 55.58.100
Requires:
Requires.private:
Conflicts:
Libs: -L${libdir} -lavutil -lm
Libs.private:
Cflags: -I${includedir}

View File

@ -0,0 +1,14 @@
prefix=/home/weixin/player3/ffmpeg/../WasmVideoPlayer-master/dist
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: libswresample
Description: FFmpeg audio resampling library
Version: 2.7.100
Requires: libavutil >= 55.58.100
Requires.private:
Conflicts:
Libs: -L${libdir} -lswresample -lm
Libs.private:
Cflags: -I${includedir}

View File

@ -0,0 +1,14 @@
prefix=/home/weixin/player3/ffmpeg/../WasmVideoPlayer-master/dist
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: libswscale
Description: FFmpeg image rescaling library
Version: 4.6.100
Requires: libavutil >= 55.58.100
Requires.private:
Conflicts:
Libs: -L${libdir} -lswscale -lm
Libs.private:
Cflags: -I${includedir}

View File

@ -0,0 +1,377 @@
function CmsParser() {
this.CMS_FLAG_FORMAT_FOUND = 0x01;
this.CMS_FLAG_TRACK_FOUND = 0x02;
this.CMS_FLAG_STOP_WHEN_ERROR = 0x04;
this.CMS_PART_UNKNOWN = 'na';
this.CMS_PART_H264_i_FRAME = 'i';
this.CMS_PART_H264_p_FRAME = 'p';
this.CMS_PART_AUDIO = 'a';
this.CMS_PART_JPG = 'j';
this.CMS_E_HEADER_FIELD = 0;
this.CMS_E_HEADER_END = 1;
this.CMS_E_PART_HEADER = 2;
this.CMS_E_PART_HEADER_FIELD = 3;
this.CMS_E_PART_HEADER_END = 4;
this.CMS_E_PART_END = 5;
this.CMS_E_CHUNK = 6;
this.CMS_E_PARSE_FAIL = 7;
this.CMS_HEADER = 0;
this.CMS_DETECT_BOUNDARY = 1;
this.CMS_PART_HEADER = 2;
this.CMS_FINISHED = 3;
this.CMS_FAIL = 4;
this.flag = 0;
this.shift = 0;
this.line_buf = new Uint8Array(2000);
this.line_buf_ptr = 0;
this.state = this.CMS_HEADER;
this.cache = new Uint8Array(100); // for boundary
this.cached_len = 0;
this.is_first_part = true;
this.callback_context = null;
this.callback = null;
this.boundary = null;
this.boundary_size = 0;
this.boundary_ptr = 0;
// boundary = strdup("\r\n----asdfasdf\r\n");
// boundary.length = strlen(boundary);
this._header = {
hasAudio: false,
hasVideo: false
};
this.parts = [];
this.part = {
header: {},
shift: 0,
chunks: []
};
};
CmsParser.prototype.fail = function (error) {
this.emit(this.CMS_E_PARSE_FAIL, error);
if (this.flag & this.CMS_FLAG_STOP_WHEN_ERROR) {
this.state = this.CMS_FAIL;
return true;
} else {
this.state = this.CMS_DETECT_BOUNDARY;
return false;
}
}
CmsParser.prototype.parse = function (data) {
var chunk = 0;
for (var i = 0; i < data.length; i++) {
var ch = data[i];
ch = String.fromCharCode(ch);
this.shift++;
switch (this.state) {
case this.CMS_FAIL: {
if (this.fail("CmsParser parse stoped.")) {
return;
}
break;
};
case this.CMS_HEADER: {
if (ch === '\r') {
} else if (ch === '\n') {
if (this.line_buf_ptr === 0) {
this.emit(this.CMS_E_HEADER_END);
if (!this.boundary) {
if (this.fail("Boundary not found.")) {
return;
}
} else if (!(this.flag & this.CMS_FLAG_FORMAT_FOUND)) {
if (this.fail("Format not found.")) {
return;
}
} else if (!(this.flag & this.CMS_FLAG_TRACK_FOUND)) {
if (this.fail("Track not found.")) {
return;
}
} else {
this.state = this.CMS_DETECT_BOUNDARY;
this.boundary_ptr = 2;
chunk = i + 1;
}
} else {
var s = String.fromCharCode.apply(null, this.line_buf.slice(0, this.line_buf_ptr));
s = s.split(":");
var key = s.shift().trim();
var value = s.join(":").trim();
// console.log("cms header:", key, '=', value);
if (key && value) {
if (key === "boundary") {
this.boundary = "\r\n--" + value + "\r\n";
} else if (key === "format" && value === "cms") {
this.flag = this.flag | this.CMS_FLAG_FORMAT_FOUND;
} else if (key === "track") {
this.flag = this.flag | this.CMS_FLAG_TRACK_FOUND;
}
var kv = {
key: key,
value: value
};
this.emit(this.CMS_E_HEADER_FIELD, kv);
} else {
if (this.fail("Invalid key value.")) {
return;
}
}
}
this.line_buf_ptr = 0;
this.line_buf.fill(0);
} else {
this.line_buf[this.line_buf_ptr] = ch.charCodeAt(0);
this.line_buf_ptr++;
}
break;
};
case this.CMS_DETECT_BOUNDARY: {
if (!this.boundary) {
break;
}
if (ch == this.boundary[this.boundary_ptr]) {
this.boundary_ptr++;
} else if (this.boundary_ptr == 1 && ch == this.boundary[this.boundary_ptr - 1]) {
} else {
if (this.cached_len > 0) {
this.emit(this.CMS_E_CHUNK, this.cache.slice(0, this.cached_len));
this.cached_len = 0;
}
this.boundary_ptr = 0;
}
if (this.boundary_ptr === this.boundary.length) {
if (i - chunk >= (this.boundary.length - this.cached_len)) {
var chunk_len = i - chunk - (this.boundary.length - this.cached_len) + 1;
this.emit(this.CMS_E_CHUNK, data.slice(chunk, chunk + chunk_len));
}
this.cached_len = 0;
if (this.is_first_part) {
this.is_first_part = false;
} else {
this.emit(this.CMS_E_PART_END);
}
this.emit(this.CMS_E_PART_HEADER);
this.state = this.CMS_PART_HEADER;
this.part = {
header: {
type: this.CMS_PART_UNKNOWN,
track: -1,
length: 0,
ts: -1
},
shift: this.shift,
chunks: []
}
chunk = i + 1;
this.boundary_ptr = 0;
this.line_buf_ptr = 0;
this.line_buf[0] = 0;
}
break;
};
case this.CMS_PART_HEADER: {
if (ch == '\r') {
} else if (ch == '\n') {
if (this.line_buf_ptr == 0) {
this.emit(this.CMS_E_PART_HEADER_END);
this.state = this.CMS_DETECT_BOUNDARY;
chunk = i + 1;
} else {
var s = String.fromCharCode.apply(null, this.line_buf.slice(0, this.line_buf_ptr)).split(":");
var key = s.shift().trim();
var value = s.join(":").trim();
// console.log("part header:", key, '=', value);
if (key && value) {
if (key === "f") {
if (value === "i") {
this.part.header.type = this.CMS_PART_H264_i_FRAME;
} else if (value === "p") {
this.part.header.type = this.CMS_PART_H264_p_FRAME;
} else if (value === "a") {
this.part.header.type = this.CMS_PART_AUDIO;
} else if (value === "j") {
this.part.header.type = this.CMS_PART_JPG;
} else {
console.error("Unknown frame type:", value);
}
} else if (key === "ts") {
this.part.header.ts = parseInt(value, 10);
} else if (key === "l") {
this.part.header.length = parseInt(value, 10);
} else if (key === "t") {
this.part.header.track = parseInt(value, 10);
}
var kv = {
key: key,
value: value
};
this.emit(this.CMS_E_PART_HEADER_FIELD, kv);
} else {
if (this.fail("Part header Invalid key value.")) {
return;
}
}
}
this.line_buf_ptr = 0;
this.line_buf.fill(0);
} else {
if (this.line_buf_ptr < this.line_buf.length - 1) {
this.line_buf[this.line_buf_ptr] = ch.charCodeAt(0);
this.line_buf_ptr++;
} else {
if (this.fail("Part header line too long.")) {
return;
}
}
}
break;
};
}
}
if (this.state == this.CMS_DETECT_BOUNDARY) {
if (chunk < data.length) {
if (this.boundary_ptr > 0) {
this.cached_len = this.boundary_ptr;
var pos = data.length - this.boundary_ptr;
if (pos >= 0) {
this.cache = data.slice(pos, this.cached_len);
}
}
this.emit(this.CMS_E_CHUNK, data.slice(chunk, chunk + data.length - chunk - this.boundary_ptr));
}
}
};
CmsParser.prototype.set_callback = function (cb, context) {
this.callback = cb;
this.callback_context = context;
};
CmsParser.prototype.emit = function (e, data, size) {
if (this.callback) {
return this.callback(this, e, data, size, this.callback_context);
} else {
this.cache_data(e, data);
}
};
CmsParser.prototype.cache_data = function (e, data) {
switch (e) {
case this.CMS_E_HEADER_FIELD: {
var key = data.key;
var value = data.value;
this._header[key] = value;
if (key === 'track') {
var tracks = value.split(';');
this._header.tracks = [];
for (var t = 0; t < tracks.length; t++) {
var fields = tracks[t].split(',');
var track = {};
for (var j = 0; j < fields.length; j++) {
var f = fields[j].split('=');
var key = f.shift();
var value = f.join('=');
track[key] = value;
if (key === 'codec') {
if (value === 'alaw') {
this._header.hasAudio = true;
this._header.audioTrack = track;
} else if (value === 'h264') {
this._header.hasVideo = true;
this._header.videoTrack = track;
}
}
}
this._header.tracks.push(track);
}
} else if (key === "duration") {
this._header.duration = parseInt(value, 10);
}
break;
};
case this.CMS_E_HEADER_END: {
this.header = this._header;
break;
};
case this.CMS_E_PART_HEADER: {
break;
};
case this.CMS_E_PART_HEADER_FIELD: {
break;
};
case this.CMS_E_PART_HEADER_END: {
break;
};
case this.CMS_E_PART_END: {
var chunks = this.part.chunks;
var size = 0;
for (var i = 0; i < chunks.length; i++) {
size = size + chunks[i].length;
}
this.part.data = new ArrayBuffer(size);
var data = new Uint8Array(this.part.data);
var shift = 0;
for (var i = 0; i < chunks.length; i++) {
data.set(chunks[i], shift);
shift = shift + chunks[i].length;
}
this.parts.push(this.part);
break;
};
case this.CMS_E_CHUNK: {
this.part.chunks.push(data);
break;
};
case this.CMS_E_PARSE_FAIL: {
break;
};
}
};
module.exports = CmsParser;
// var cms = new CmsParser();
// var fs = require('fs');
// var f = fs.createReadStream("/home/gxy/work/cms/cms/tmp/ttt.cms");
// f.on('end', function (err) {
// console.log("end");
// });
// f.on('error', function (err) {
// console.error(err);
// });
// f.on('data', function (chunk) {
// cms.parse(chunk);
// if (cms.header) {
// console.log(cms.header);
// cms.header = null;
// }
// var parts = cms.parts;
// while (parts.length > 0) {
// var part = parts.shift();
// console.log(part.header);
// var chunks = part.chunks;
// var len = 0;
// for (var i = 0; i < chunks.length; i++) {
// len = len + chunks[i].length;
// }
// if (len !== part.header.length) {
// console.log("mismatch: len=%d part.len=%d", len, part.header.length);
// }
// }
// });

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1,204 @@
function PCMPlayer(option) {
console.log("PCMPlayer new")
this.init(option);
}
PCMPlayer.prototype.init = function (option) {
var defaults = {
encoding: '16bitInt',
channels: 1,
sampleRate: 8000,
flushingTime: 1000
};
this.option = Object.assign({}, defaults, option);
this.samples = new Float32Array();
this.flush = this.flush.bind(this);
this.interval = setInterval(this.flush, this.option.flushingTime);
this.maxValue = this.getMaxValue();
this.typedArray = this.getTypedArray();
this.createContext();
this.lastBufferSource = null
};
PCMPlayer.prototype.getMaxValue = function () {
var encodings = {
'8bitInt': 128,
'16bitInt': 32768,
'32bitInt': 2147483648,
'32bitFloat': 1
}
return encodings[this.option.encoding] ? encodings[this.option.encoding] : encodings['16bitInt'];
};
PCMPlayer.prototype.getTypedArray = function () {
var typedArrays = {
'8bitInt': Int8Array,
'16bitInt': Int16Array,
'32bitInt': Int32Array,
'32bitFloat': Float32Array
}
return typedArrays[this.option.encoding] ? typedArrays[this.option.encoding] : typedArrays['16bitInt'];
};
PCMPlayer.prototype.createContext = function () {
this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();
this.gainNode = this.audioCtx.createGain();
this.gainNode.gain.value = 1;
this.gainNode.connect(this.audioCtx.destination);
this.startTime = this.audioCtx.currentTime;
};
PCMPlayer.prototype.isTypedArray = function (data) {
return (data.byteLength && data.buffer && data.buffer.constructor == ArrayBuffer);
};
PCMPlayer.prototype.feed = function (data) {
if (!this.isTypedArray(data)) return;
data = this.getFormatedValue(data);
var tmp = new Float32Array(this.samples.length + data.length);
tmp.set(this.samples, 0);
tmp.set(data, this.samples.length);
this.samples = tmp;
};
PCMPlayer.prototype.getFormatedValue = function (data) {
var data = new this.typedArray(data.buffer),
float32 = new Float32Array(data.length),
i;
for (i = 0; i < data.length; i++) {
float32[i] = data[i] / this.maxValue;
}
return float32;
};
PCMPlayer.prototype.volume = function (volume) {
this.gainNode.gain.value = volume;
};
PCMPlayer.prototype.destroy = function () {
console.log("PCMPlayer destroy")
if (this.interval) {
clearInterval(this.interval);
}
this.samples = null;
this.audioCtx.close();
this.audioCtx = null;
};
PCMPlayer.prototype.flush = function () {
// console.log("PCMPlayer.prototype.flush", this.samples.length)
if (!this.samples.length) return;
var bufferSource = this.audioCtx.createBufferSource(),
length = this.samples.length / this.option.channels,
audioBuffer = this.audioCtx.createBuffer(this.option.channels, length, this.option.sampleRate),
audioData,
channel,
offset,
i,
decrement;
for (channel = 0; channel < this.option.channels; channel++) {
audioData = audioBuffer.getChannelData(channel);
offset = channel;
decrement = 50;
for (i = 0; i < length; i++) {
audioData[i] = this.samples[offset];
/* fadein */
if (i < 50) {
audioData[i] = (audioData[i] * i) / 50;
}
/* fadeout*/
if (i >= (length - 51)) {
audioData[i] = (audioData[i] * decrement--) / 50;
}
offset += this.option.channels;
}
}
if (this.startTime < this.audioCtx.currentTime) {
this.startTime = this.audioCtx.currentTime;
}
// console.log('start vs current '+this.startTime+' vs '+this.audioCtx.currentTime+' duration: '+audioBuffer.duration);
bufferSource.buffer = audioBuffer;
bufferSource.connect(this.gainNode);
bufferSource.start(this.startTime);
this.startTime += audioBuffer.duration;
this.samples = new Float32Array();
};
PCMPlayer.prototype.getTimestamp = function () {
if (this.audioCtx) {
return this.audioCtx.currentTime;
} else {
return 0;
}
};
PCMPlayer.prototype.play = function (data, flushcache) {
if (!this.isTypedArray(data)) {
return;
}
if (this.audioCtx.state === 'suspended') {
return;
}
data = this.getFormatedValue(data);
if (!data.length) {
return;
}
var bufferSource = this.audioCtx.createBufferSource();
var length = data.length / this.option.channels;
var audioBuffer = this.audioCtx.createBuffer(this.option.channels, length, this.option.sampleRate);
var audioData, channel, offset, i, decrement;
for (channel = 0; channel < this.option.channels; channel++) {
audioData = audioBuffer.getChannelData(channel);
offset = channel;
decrement = 50;
for (i = 0; i < length; i++) {
audioData[i] = data[offset];
/* fadein */
if (i < 50) {
audioData[i] = (audioData[i] * i) / 50;
}
/* fadeout*/
if (i >= (length - 51)) {
audioData[i] = (audioData[i] * decrement--) / 50;
}
offset += this.option.channels;
}
}
if (this.startTime < this.audioCtx.currentTime) {
this.startTime = this.audioCtx.currentTime;
}
// console.log('start vs current '+this.startTime+' vs '+this.audioCtx.currentTime+' duration: '+audioBuffer.duration);
bufferSource.buffer = audioBuffer;
bufferSource.connect(this.gainNode);
bufferSource.start(this.startTime);
this.startTime += audioBuffer.duration - 0.008;
// bufferSource.playbackRate(1.05)
this.lastBufferSource = bufferSource
};
PCMPlayer.prototype.pause = function () {
if (this.audioCtx.state === 'running') {
this.audioCtx.suspend()
}
}
PCMPlayer.prototype.resume = function () {
if (this.audioCtx.state === 'suspended') {
this.audioCtx.resume()
}
}
PCMPlayer.prototype.stop = function () {
if (this.lastBufferSource)
this.lastBufferSource.stop()
}

File diff suppressed because one or more lines are too long

150
public/cw/player/webgl.js Normal file
View File

@ -0,0 +1,150 @@
function Texture(gl) {
this.gl = gl;
this.texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
}
Texture.prototype.bind = function (n, program, name) {
var gl = this.gl;
gl.activeTexture([gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2][n]);
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.uniform1i(gl.getUniformLocation(program, name), n);
};
Texture.prototype.fill = function (width, height, data) {
var gl = this.gl;
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width, height, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, data);
};
function WebGLPlayer(canvas, options) {
this.canvas = canvas;
this.gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
this.initGL(options);
}
WebGLPlayer.prototype.initGL = function (options) {
if (!this.gl) {
// console.log("[ER] WebGL not supported.");
return;
}
var gl = this.gl;
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
var program = gl.createProgram();
var vertexShaderSource = [
"attribute highp vec4 aVertexPosition;",
"attribute vec2 aTextureCoord;",
"varying highp vec2 vTextureCoord;",
"void main(void) {",
" gl_Position = aVertexPosition;",
" vTextureCoord = aTextureCoord;",
"}"
].join("\n");
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
var fragmentShaderSource = [
"precision highp float;",
"varying lowp vec2 vTextureCoord;",
"uniform sampler2D YTexture;",
"uniform sampler2D UTexture;",
"uniform sampler2D VTexture;",
"const mat4 YUV2RGB = mat4",
"(",
" 1.1643828125, 0, 1.59602734375, -.87078515625,",
" 1.1643828125, -.39176171875, -.81296875, .52959375,",
" 1.1643828125, 2.017234375, 0, -1.081390625,",
" 0, 0, 0, 1",
");",
"void main(void) {",
" gl_FragColor = vec4( texture2D(YTexture, vTextureCoord).x, texture2D(UTexture, vTextureCoord).x, texture2D(VTexture, vTextureCoord).x, 1) * YUV2RGB;",
"}"
].join("\n");
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
// console.log("[ER] Shader link failed.");
}
var vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition");
gl.enableVertexAttribArray(vertexPositionAttribute);
var textureCoordAttribute = gl.getAttribLocation(program, "aTextureCoord");
gl.enableVertexAttribArray(textureCoordAttribute);
var verticesBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, verticesBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0]), gl.STATIC_DRAW);
gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
var texCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0]), gl.STATIC_DRAW);
gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
gl.y = new Texture(gl);
gl.u = new Texture(gl);
gl.v = new Texture(gl);
gl.y.bind(0, program, "YTexture");
gl.u.bind(1, program, "UTexture");
gl.v.bind(2, program, "VTexture");
}
WebGLPlayer.prototype.renderFrame = function (videoFrame, width, height, uOffset, vOffset) {
if (!this.gl) {
// console.log("[ER] Render frame failed due to WebGL not supported.");
return;
}
var gl = this.gl;
gl.canvas.width = width;
gl.canvas.height = height;
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.y.fill(width, height, videoFrame.subarray(0, uOffset));
gl.u.fill(width >> 1, height >> 1, videoFrame.subarray(uOffset, uOffset + vOffset));
gl.v.fill(width >> 1, height >> 1, videoFrame.subarray(uOffset + vOffset, videoFrame.length));
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
};
WebGLPlayer.prototype.fullscreen = function () {
var canvas = this.canvas;
if (canvas.RequestFullScreen) {
canvas.RequestFullScreen();
} else if (canvas.webkitRequestFullScreen) {
canvas.webkitRequestFullScreen();
} else if (canvas.mozRequestFullScreen) {
canvas.mozRequestFullScreen();
} else if (canvas.msRequestFullscreen) {
canvas.msRequestFullscreen();
} else {
alert("This browser doesn't supporter fullscreen");
}
};
WebGLPlayer.prototype.exitfullscreen = function (){
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else {
alert("Exit fullscreen doesn't work");
}
}

105
public/cw_/README.html Normal file
View File

@ -0,0 +1,105 @@
<!doctype html>
<html>
<head>
<meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'>
<title>README</title>
</head>
<body><h3 id='丛文cms视频web播放器'>丛文CMS视频WEB播放器</h3>
<h4 id='1简介'>1.简介</h4>
<p>该Demo项目目前支持丛文cms格式封装的基于H264\H265压缩格式的实时视频流录像视频文件以及录像图片文件的播放。</p>
<h4 id='2操作界面介绍'>2.操作界面介绍</h4>
<p><img src="/public/help/realplayscreen.png" referrerpolicy="no-referrer"></p>
<h5 id='播放实时视频本地模拟流)'>播放实时视频(本地模拟流)</h5>
<p>此按钮为播放web服务器端一个本地丛文媒体流文件适用于没有丛文服务器环境下了解丛文web视频播放控件。</p>
<h5 id='播放录像文件本地模拟流)'>播放录像文件(本地模拟流)</h5>
<p>此按钮为回放web服务器端一个本地丛文媒体流文件适用于没有丛文服务器环境下了解丛文web视频播放控件。</p>
<h5 id='播放实时视频请配置url'>播放实时视频请配置URL</h5>
<p>此按钮为播放实时视频需要配合丛文服务器需要配置从视频输出网关获取的视频拉取url。</p>
<h5 id='播放视频对讲请配置url'>播放视频对讲请配置URL</h5>
<p>此按钮为播放实时视频并提供对讲功能需要配合丛文服务器需要配置从视频输出网关获取的视频拉取url和对讲url。</p>
<p>需要先配置好上面的视频拉取url然后配置下面的对讲rul先拉取视频才可以点击对讲按钮进行对讲。</p>
<h5 id='播放录像文件请配置url'>播放录像文件请配置URL</h5>
<p>此按钮为回放录像文件需要配合丛文服务器需要配置从视频输出网关获取的录像文件拉取url。</p>
<p>&nbsp;</p>
<h4 id='3功能说明'>3.功能说明</h4>
<ul>
<li><p>实时视频</p>
<p>播放、暂停、恢复播放、监听、对讲、全屏</p>
</li>
<li><p>录像视频</p>
<p>播放、暂停、恢复播放、播放进度跳转</p>
</li>
<li><p>图片回放</p>
<p>播放、暂停、恢复播放、播放进度跳转、红点</p>
<p>&nbsp;</p>
</li>
</ul>
<h4 id='4文件及目录说明'>4.文件及目录说明</h4>
<p>&nbsp;</p>
<figure><table>
<thead>
<tr><th>路径</th><th>说明</th></tr></thead>
<tbody><tr><td>index.html</td><td>DEMO播放页面文件</td></tr><tr><td>/public/player/</td><td>播放控件脚本</td></tr><tr><td>/public/player/cmsplayer.js</td><td>cms播放器</td></tr><tr><td>/public/player/cmsparser.js</td><td>cms解封装器</td></tr><tr><td>/public/player/decoder.js</td><td>解码器</td></tr><tr><td>/public/player/pcm-player.js</td><td>pcm播放器</td></tr><tr><td>/public/player/webgl.js</td><td>图像渲染器</td></tr><tr><td>/public/images/</td><td>用到的图片文件夹</td></tr><tr><td>/public/js/moment.js</td><td>播放控件用到的js文件</td></tr><tr><td>/public/data/</td><td>本地丛文格式媒体文件用于DEMO回放演示</td></tr></tbody>
</table></figure>
<p>&nbsp;</p>
<h4 id='5集成及接口说明'>5.集成及接口说明</h4>
<ol start='' >
<li><h5 id='导入player播放支持组件文件夹'>导入player播放支持组件文件夹</h5>
</li>
<li><h5 id='参考indexhtml在播放html页面head导入需要的脚本'>参考index.html,在播放html页面head导入需要的脚本</h5>
<script src="/public/player/cmsplayer.js"></script>
<script src="/public/player/common.js"></script>
<script src="/public/player/pcm-player.js"></script>
<script src="/public/player/webgl.js"></script>
<script src="/public/player/cmstalk.js"></script>
<script src="/public/player/alawmulaw.js"></script>
<script src="/public/player/recorder-core.js"></script>
<script src="/public/js/moment.js"></script>
</li>
<li><h5 id='初始化播放器控件'>初始化播放器控件:</h5>
<p><code>playerBox</code> 为 div id</p>
<pre><code class='language-javascript' lang='javascript'>self.player = new Player($(&quot;#playerBox&quot;));
</code></pre>
</li>
<li><h5 id='播放'>播放:</h5>
<pre><code class='language-javascript' lang='javascript'>//url 播放地址
//isLive 是否实时视频
//alarmTime 告警红点时间戳
self.player.play(url, isLive , alarmTime );
</code></pre>
</li>
<li><h5 id='暂停播放'>暂停播放:</h5>
<pre><code class='language-javascript' lang='javascript'>self.player.pause();
</code></pre>
</li>
<li><h5 id='恢复播放'>恢复播放:</h5>
<pre><code class='language-javascript' lang='javascript'>self.player.resume();
</code></pre>
</li>
<li><h5 id='停止播放'>停止播放:</h5>
<pre><code class='language-javascript' lang='javascript'>self.player.stop();
</code></pre>
</li>
<li><h5 id='监听开始'>监听开始:</h5>
<pre><code class='language-javascript' lang='javascript'>self.player.startListen();
</code></pre>
</li>
<li><h5 id='监听结束'>监听结束:</h5>
<pre><code class='language-javascript' lang='javascript'>self.player.stopListen();
</code></pre>
</li>
<li><h5 id='全屏'>全屏:</h5>
<pre><code class='language-javascript' lang='javascript'>self.player.fullscreen();
</code></pre>
</li>
</ol>
<h4 id='6运行方法'>6.运行方法</h4>
<h5 id='运行整合了win版nginx的'>运行整合了win版nginx的</h5>
<p>直接运行nginx然后打开浏览器输入 <a href='http://localhost/index.html' target='_blank' class='url'>http://localhost/index.html</a></p>
<h5 id='自己运行web服务器的'>自己运行web服务器的</h5>
<p>拷贝 相关文件到 web 网站的根目录。</p>
<h5 ></h5>
</body>
</html>

146
public/cw_/README.md Normal file
View File

@ -0,0 +1,146 @@
### 丛文CMS视频WEB播放器
#### 1.简介
该Demo项目目前支持丛文cms格式封装的基于H264\H265压缩格式的实时视频流录像视频文件以及录像图片文件的播放。
#### 2.操作界面介绍
![](/home/ramon/Pictures/realplayscreen.png)
##### 播放实时视频(本地模拟流)
此按钮为播放web服务器端一个本地丛文媒体流文件适用于没有丛文服务器环境下了解丛文web视频播放控件。
##### 播放录像文件(本地模拟流)
此按钮为回放web服务器端一个本地丛文媒体流文件适用于没有丛文服务器环境下了解丛文web视频播放控件。
##### 播放实时视频请配置URL
此按钮为播放实时视频需要配合丛文服务器需要配置从视频输出网关获取的视频拉取url。
##### 播放视频对讲请配置URL
此按钮为播放实时视频并提供对讲功能需要配合丛文服务器需要配置从视频输出网关获取的视频拉取url和对讲url。
##### 播放录像文件请配置URL
此按钮为回放录像文件需要配合丛文服务器需要配置从视频输出网关获取的录像文件拉取url。
#### 3.功能说明
- 实时视频
播放、暂停、恢复播放、监听、对讲、全屏
- 录像视频
播放、暂停、恢复播放、播放进度跳转
- 图片回放
播放、暂停、恢复播放、播放进度跳转、红点
#### 4.文件及目录说明
| 路径 | 说明 |
| ---------------------------- | -------------------------------------- |
| index.html | DEMO播放页面文件 |
| /public/player/ | 播放控件脚本 |
| /public/player/cmsplayer.js | cms播放器 |
| /public/player/cmsparser.js | cms解封装器 |
| /public/player/decoder.js | 解码器 |
| /public/player/pcm-player.js | pcm播放器 |
| /public/player/webgl.js | 图像渲染器 |
| /public/images/ | 用到的图片文件夹 |
| /public/js/moment.js | 播放控件用到的js文件 |
| /public/data/ | 本地丛文格式媒体文件用于DEMO回放演示 |
#### 5.集成及接口说明
1. ##### 导入player播放支持组件文件夹
2. ##### 参考index.html,在播放html页面head导入需要的脚本
<script src="/public/player/cmsplayer.js"></script>
<script src="/public/player/common.js"></script>
<script src="/public/player/pcm-player.js"></script>
<script src="/public/player/webgl.js"></script>
<script src="/public/player/cmstalk.js"></script>
<script src="/public/player/alawmulaw.js"></script>
<script src="/public/player/recorder-core.js"></script>
<script src="/public/js/moment.js"></script>
3. ##### 初始化播放器控件:
`playerBox` 为 div id
```javascript
self.player = new Player($("#playerBox"));
```
4. ##### 播放:
```javascript
//url 播放地址
//isLive 是否实时视频
//alarmTime 告警红点时间戳
self.player.play(url, isLive , alarmTime );
```
5. ##### 暂停播放:
```javascript
self.player.pause();
```
6. ##### 恢复播放:
```javascript
self.player.resume();
```
7. ##### 停止播放:
```javascript
self.player.stop();
```
8. ##### 监听开始:
```javascript
self.player.startListen();
```
9. ##### 监听结束:
```javascript
self.player.stopListen();
```
10. ##### 全屏:
```javascript
self.player.fullscreen();
```
#### 6.运行方法
##### 运行整合了win版nginx的
直接运行nginx然后打开浏览器输入 http://localhost/index.html
##### 自己运行web服务器的
拷贝 相关文件到 web 网站的根目录。
#####

107
public/cw_/index.html Normal file
View File

@ -0,0 +1,107 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0" />
<title>CMS Player</title>
<link rel="shortcut icon" href="#" />
<script src="./public/player/cmsplayer.js"></script>
<script src="./public/player/common.js"></script>
<script src="./public/player/pcm-player.js"></script>
<script src="./public/player/webgl.js"></script>
<script src="./public/player/cmstalk.js"></script>
<script src="./public/player/alawmulaw.js"></script>
<script src="./public/player/recorder-core.js"></script>
<script src="./public/js/moment.js"></script>
<script src="./public/js/axios.min.js"></script>
<script src="./public/js/jquery-2.2.3.min.js"></script>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
/* padding: 30px; */
box-sizing: border-box;
}
div {
user-select: none;
-ms-user-select: none;
-moz-user-select: none;
-html-user-select: none;
-webkit-user-select: none;
}
ul {
list-style: none;
}
ul li {
height: 100%;
float: left;
box-sizing: border-box;
}
#videoTimeTrack li {
border-right: 1px solid #ccc;
}
#videoTimeTrack li:first-child {
border-left: 1px solid #ccc;
}
#playerBox {
height: 100%;
width: 100%;
}
</style>
</head>
<body ontouchstart>
<div id="playerBox"></div>
<script type="text/javascript">
window.onload = function () {
self.player = new Player($("#playerBox"));
function getParams(key) {
var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) {
return decodeURIComponent(r[2]); // 使用 decodeURIComponent 代替 unescape
}
return null;
}
var locationUrl = window.location.href;
var id = getParams("id");
var title = getParams("title");
let requestBody = {
pointId: id
}
console.log(window.location, locationUrl, id, title);
try {
let url = 'http://175.6.124.250:8083/multialarm/video/preview'
axios({
method: 'post',
url,
data: { ...requestBody }
}).then(res => {
console.log(res);
var PLAYURL = res.data.data.videoUrl
self.player.play(PLAYURL, true, "");
}).catch(function (error) {
console.log(error)
})
} catch (error) {
console.log(error);
}
$("html>head>title").html(title);
}
</script>
</body>
</html>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

View File

@ -0,0 +1 @@
<svg t="1665647640241" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4863" width="32" height="32"><path d="M512 422.4c-70.4 0-128 57.6-128 128s57.6 128 128 128 128-57.6 128-128-57.6-128-128-128z" p-id="4864" fill="#ffffff"></path><path d="M940.8 198.4h-208V144c0-19.2-16-38.4-38.4-38.4h-368c-19.2 0-38.4 16-38.4 38.4v54.4H80c-28.8 0-51.2 22.4-51.2 51.2v620.8c0 28.8 22.4 51.2 51.2 51.2h860.8c28.8 0 51.2-22.4 51.2-51.2V249.6c0-28.8-22.4-51.2-51.2-51.2zM512 771.2c-121.6 0-220.8-99.2-220.8-220.8 0-121.6 99.2-220.8 220.8-220.8s220.8 99.2 220.8 220.8c0 121.6-99.2 220.8-220.8 220.8z m368-460.8H732.8v-35.2H880v35.2z" p-id="4865" fill="#ffffff"></path></svg>

After

Width:  |  Height:  |  Size: 702 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1646746198883" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3880" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M820.053333 205.077333a42.666667 42.666667 0 0 1 1.408 57.664l-2.538666 2.666667L562.837333 512l256.085334 246.613333a42.666667 42.666667 0 0 1-56.426667 63.893334l-2.773333-2.432L501.333333 571.221333 242.922667 820.074667a42.666667 42.666667 0 0 1-61.717334-58.816l2.538667-2.666667L439.808 512 183.744 265.386667a42.666667 42.666667 0 0 1 56.426667-63.893334l2.773333 2.432 258.368 248.832L759.744 203.925333a42.666667 42.666667 0 0 1 60.330667 1.152z" p-id="3881" fill="#ffffff"></path></svg>

After

Width:  |  Height:  |  Size: 871 B

View File

@ -0,0 +1 @@
<svg t="1665649555889" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2290" width="32" height="32"><path d="M511.883031 56.77603c-250.925838 0-455.090006 204.166167-455.090006 455.092005v244.611503c0 108.255456 88.059781 196.257252 196.258252 196.257252 80.037896 0 145.061751-65.020856 145.061752-145.002767V642.706536c0-79.978912-65.021856-145.061751-145.061752-145.061751a195.335496 195.335496 0 0 0-110.92975 34.643865v-20.417616c0-203.881242 165.881262-369.762504 369.760504-369.762504s369.760505 165.881262 369.760505 369.762504v20.421615a195.059568 195.059568 0 0 0-110.927752-34.643865c-79.978912 0-145.061751 65.082839-145.061751 145.061751v165.023488c0 79.978912 65.082839 145.002767 145.061751 145.002767 108.197471 0 196.258252-88.001796 196.258252-196.257252V511.871034c0.001-250.933836-204.164168-455.095004-455.090005-455.095004zM253.051277 582.976286a59.759243 59.759243 0 0 1 59.729252 59.73025v165.027487a59.711256 59.711256 0 0 1-59.729252 59.673266A111.070714 111.070714 0 0 1 142.121527 756.479538v-62.518516a111.08371 111.08371 0 0 1 110.92975-110.985736z m628.592258 173.503252A111.070714 111.070714 0 0 1 770.715784 867.408289a59.748246 59.748246 0 0 1-59.730251-59.673266V642.706536A59.796233 59.796233 0 0 1 770.715784 582.976286a111.082711 111.082711 0 0 1 110.927751 110.985736v62.518515z" p-id="2291" fill="#ffffff"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1646745129934" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1383" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M768 298.666667h170.666667v85.333333h-256V128h85.333333v170.666667zM341.333333 384H85.333333V298.666667h170.666667V128h85.333333v256z m426.666667 341.333333v170.666667h-85.333333v-256h256v85.333333h-170.666667zM341.333333 640v256H256v-170.666667H85.333333v-85.333333h256z" p-id="1384" fill="#ffffff"></path></svg>

After

Width:  |  Height:  |  Size: 688 B

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M18,32V52a4.012,4.012,0,0,0,4,4H62a4.012,4.012,0,0,0,4-4V32a4.012,4.012,0,0,0-4-4H22A4.012,4.012,0,0,0,18,32Zm6,2H60V50H24ZM7,36a3,3,0,0,0,3-3V23a3,3,0,0,1,3-3H23a3,3,0,0,0,0-6H13a9.01,9.01,0,0,0-9,9V33A3,3,0,0,0,7,36ZM71,14H61a3,3,0,0,0,0,6H71a3,3,0,0,1,3,3V33a3,3,0,0,0,6,0V23A9.01,9.01,0,0,0,71,14Zm6,34a3,3,0,0,0-3,3V61a3,3,0,0,1-3,3H61a3,3,0,0,0,0,6H71a9.01,9.01,0,0,0,9-9V51A3,3,0,0,0,77,48ZM23,64H13a3,3,0,0,1-3-3V51a3,3,0,0,0-6,0V61a9.01,9.01,0,0,0,9,9H23a3,3,0,0,0,0-6Z"/></svg>

After

Width:  |  Height:  |  Size: 682 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1646745119141" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1430" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M213.333333 213.333333h213.333334V128H170.666667a42.666667 42.666667 0 0 0-42.666667 42.666667v256h85.333333V213.333333zM170.666667 896h256v-85.333333H213.333333v-213.333334H128v256a42.666667 42.666667 0 0 0 42.666667 42.666667z m725.333333-42.666667v-256h-85.333333v213.333334h-213.333334v85.333333h256a42.666667 42.666667 0 0 0 42.666667-42.666667zM597.333333 213.333333h213.333334v213.333334h85.333333V170.666667a42.666667 42.666667 0 0 0-42.666667-42.666667h-256v85.333333z" fill="#ffffff" p-id="1431"></path></svg>

After

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<title>视频操作</title>
<g>
<path class="st0" d="M49.3,42.2c1.8-3,2.7-6.4,2.7-10.2v-4.6c0-0.6-0.2-1.2-0.7-1.6s-1-0.7-1.6-0.7s-1.2,0.2-1.6,0.7
s-0.7,1-0.7,1.6V32c0,2.5-0.5,4.7-1.5,6.8L49.3,42.2z"/>
<path class="st0" d="M31,43.5c1.7,0,3.2-0.3,4.6-0.9L19.3,26.4V32c0,3.2,1.1,5.9,3.4,8.2S27.8,43.5,31,43.5z"/>
<path class="st0" d="M42.7,57.4h-9.3v-4.8c3.4-0.4,6.4-1.4,9.1-3.2L39,46.1c-2.4,1.4-5.1,2.1-8,2.1c-4.5,0-8.3-1.6-11.5-4.7
c-3.2-3.2-4.8-7-4.8-11.4v-4.6c0-0.6-0.2-1.2-0.7-1.6c-0.5-0.5-1-0.7-1.6-0.7s-1.2,0.2-1.6,0.7c-0.5,0.5-0.7,1-0.7,1.6V32
c0,5.3,1.8,9.9,5.4,13.9c3.6,3.9,8,6.2,13.3,6.8v4.8h-9.3c-0.6,0-1.2,0.2-1.6,0.7s-0.7,1-0.7,1.6s0.2,1.2,0.7,1.6s1,0.7,1.6,0.7
h23.3c0.6,0,1.2-0.2,1.6-0.7s0.7-1,0.7-1.6s-0.2-1.2-0.7-1.6S43.3,57.4,42.7,57.4z"/>
<path class="st0" d="M42.2,35.2c0.3-1,0.4-2.1,0.4-3.2V13.5c0-3.2-1.1-5.9-3.4-8.2S34.2,2,31,2s-6,1.1-8.2,3.4c-2,2-3.1,4.3-3.4,7
L42.2,35.2z"/>
</g>
<path class="st0" d="M50.9,55.1l-42-42c-1.2-1.2-1.2-3,0-4.2l0,0c1.2-1.2,3-1.2,4.2,0L55.2,51c1.2,1.2,1.2,3,0,4.2l0,0
C54,56.3,52.1,56.3,50.9,55.1z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<title>视频操作</title>
<path class="st0" d="M52,27.4V32c0,5.3-1.8,9.9-5.4,13.9s-8,6.2-13.3,6.8v4.8h9.3c0.6,0,1.2,0.2,1.6,0.7c0.5,0.5,0.7,1,0.7,1.6
s-0.2,1.2-0.7,1.6c-0.5,0.5-1,0.7-1.6,0.7H19.3c-0.6,0-1.2-0.2-1.6-0.7c-0.5-0.5-0.7-1-0.7-1.6s0.2-1.2,0.7-1.6
c0.5-0.5,1-0.7,1.6-0.7h9.3v-4.8c-5.3-0.6-9.7-2.8-13.3-6.8c-3.5-4-5.3-8.6-5.3-13.9v-4.6c0-0.6,0.2-1.2,0.7-1.6
c0.5-0.5,1-0.7,1.6-0.7s1.2,0.2,1.6,0.7c0.5,0.5,0.7,1,0.7,1.6V32c0,4.4,1.6,8.3,4.8,11.4c3.2,3.2,7,4.7,11.5,4.7s8.3-1.6,11.5-4.7
c3.2-3.2,4.8-7,4.8-11.4v-4.6c0-0.6,0.2-1.2,0.7-1.6c0.5-0.5,1-0.7,1.6-0.7s1.2,0.2,1.6,0.7C51.8,26.2,52,26.8,52,27.4z M42.7,13.5
V32c0,3.2-1.1,5.9-3.4,8.2c-2.3,2.3-5,3.4-8.2,3.4s-6-1.1-8.2-3.4s-3.4-5-3.4-8.2V13.5c0-3.2,1.1-5.9,3.4-8.2S27.8,2,31,2
s6,1.1,8.2,3.4S42.7,10.4,42.7,13.5z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M44.269,12a4.385,4.385,0,0,0-2.5.816L23.264,27.05H16.71A7.625,7.625,0,0,0,9,34.542V49.525a7.625,7.625,0,0,0,7.71,7.491h6.554l18.5,14.234a3.387,3.387,0,0,0,2.161.75,3.96,3.96,0,0,0,4.007-3.746V15.813A3.625,3.625,0,0,0,44.269,12ZM41.936,61.779a1,1,0,0,1-1.61.792L26.922,52.26,25.3,51.016H16.71A1.634,1.634,0,0,1,15,49.525V34.542a1.634,1.634,0,0,1,1.71-1.492H25.3l1.618-1.244L40.326,21.5a1,1,0,0,1,1.61.792ZM67.78,42.845,74.125,36.5a3,3,0,0,0-4.243-4.243L63.537,38.6l-6.345-6.345A3,3,0,0,0,52.95,36.5L59.3,42.845,52.95,49.19a3,3,0,1,0,4.242,4.242l6.345-6.345,6.345,6.345a3.009,3.009,0,0,0,4.243,0h0a3.008,3.008,0,0,0,0-4.242Z"/></svg>

After

Width:  |  Height:  |  Size: 826 B

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M27,18a3.009,3.009,0,0,0-3,3V63a3,3,0,0,0,6,0V21A3.009,3.009,0,0,0,27,18Zm30,0a3.009,3.009,0,0,0-3,3V63a3,3,0,0,0,6,0V21A3.009,3.009,0,0,0,57,18Z"/></svg>

After

Width:  |  Height:  |  Size: 349 B

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M66,15H18A12.035,12.035,0,0,0,6,27V57A12.035,12.035,0,0,0,18,69H66A12.035,12.035,0,0,0,78,57V27A12.035,12.035,0,0,0,66,15Zm6,42a6.007,6.007,0,0,1-6,6H18a6.011,6.011,0,0,1-5.877-4.787l12.934-11.3a3.051,3.051,0,0,1,.976-.476,1.315,1.315,0,0,1,.319-.046.8.8,0,0,1,.595.308c2.918,2.919,6.069,6.484,6.186,6.616a5.184,5.184,0,0,0,3.538,1.855c.1.007.209.011.32.011a5.27,5.27,0,0,0,3.749-1.655c.675-.649,10.811-10.129,14.608-13.666l.115-.116a3.742,3.742,0,0,1,2.235-1.06,2.742,2.742,0,0,1,1.877,1.04C62.048,42.329,68.2,51.055,72,56.7Zm0-10.483a96.045,96.045,0,0,0-8.045-10.945,8.538,8.538,0,0,0-6.27-2.922,9.745,9.745,0,0,0-6.5,2.834c-.885.823-11.464,10.7-14.107,13.2-1.888-2.115-3.856-4.212-5.854-6.238a6.787,6.787,0,0,0-6.953-1.777A8.755,8.755,0,0,0,21.313,42.2l-.056.035L12,50.219V27a6.007,6.007,0,0,1,6-6H66a6.007,6.007,0,0,1,6,6ZM25,26a4,4,0,1,0,4,4A4,4,0,0,0,25,26Z"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M27,22.264,55.5,42,27,61.736V22.264M25.565,15A4.394,4.394,0,0,0,21,19.211V64.789A4.394,4.394,0,0,0,25.565,69a4.722,4.722,0,0,0,2.707-.847L61.179,45.364a4.018,4.018,0,0,0,0-6.728L28.272,15.847A4.722,4.722,0,0,0,25.565,15Z"/></svg>

After

Width:  |  Height:  |  Size: 424 B

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M73.4,40.52a3.12,3.12,0,0,0-3.138,3.094v.922a17.223,17.223,0,0,1-17.23,17.178H19.262v-6.7a.4.4,0,0,0-.239-.361.433.433,0,0,0-.46.064l-11.424,9.8a.388.388,0,0,0,0,.594L18.565,74.9a.429.429,0,0,0,.279.1.434.434,0,0,0,.179-.039.4.4,0,0,0,.239-.356v-6.7h33.77a23.463,23.463,0,0,0,23.5-23.371v-.922A3.118,3.118,0,0,0,73.4,40.52Zm3.462-21.626L65.435,9.1a.433.433,0,0,0-.279-.1.438.438,0,0,0-.178.038.4.4,0,0,0-.239.354v6.7H30.968a23.463,23.463,0,0,0-23.5,23.371v.921a3.135,3.135,0,0,0,6.269,0v-.921a17.225,17.225,0,0,1,17.23-17.179H64.739v6.7a.4.4,0,0,0,.241.36.415.415,0,0,0,.177.039.428.428,0,0,0,.277-.1l11.425-9.8a.4.4,0,0,0,.141-.3A.393.393,0,0,0,76.862,18.894ZM33.607,38.067a3.151,3.151,0,0,1-1.3-.281l-3.715-1.664-.49,4.041A14.237,14.237,0,1,0,42.229,27.727a14.3,14.3,0,0,0-4.677.783l-3.9,1.347,2.484,3.3a3.023,3.023,0,0,1,.618,1.827A3.121,3.121,0,0,1,33.607,38.067Zm9.147-3.088a8.973,8.973,0,0,0-.085-1.241,8.128,8.128,0,1,1-8.368,10.3A9.125,9.125,0,0,0,42.754,34.979Z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84 84"><defs><style>.cls-1{fill:#FFFFFF;}</style></defs><title>视频操作</title><path class="cls-1" d="M59.818,17.687a2.887,2.887,0,0,0-3.936,1.092A3.1,3.1,0,0,0,57.287,22.6,20.827,20.827,0,0,1,69.1,42.273a20.949,20.949,0,0,1-12.09,19.4,2.382,2.382,0,0,0-1.124,3.552,2.887,2.887,0,0,0,3.936,1.092,27.059,27.059,0,0,0,0-48.626Zm3.374,24.257a15.4,15.4,0,0,0-5.624-12.02,3.078,3.078,0,0,0-3.936.273,2.587,2.587,0,0,0,0,3.825,10.5,10.5,0,0,1,0,16.391c-1.124.819-1.124,2.732,0,3.278a2.77,2.77,0,0,0,3.936.273A15.4,15.4,0,0,0,63.192,41.944ZM44.269,12a4.385,4.385,0,0,0-2.5.816L23.264,27.05H16.71A7.625,7.625,0,0,0,9,34.542V49.525a7.625,7.625,0,0,0,7.71,7.491h6.554l18.5,14.234a3.387,3.387,0,0,0,2.161.75,3.96,3.96,0,0,0,4.007-3.746V15.813A3.625,3.625,0,0,0,44.269,12ZM41.936,61.779a1,1,0,0,1-1.61.792L26.922,52.26,25.3,51.016H16.71A1.634,1.634,0,0,1,15,49.525V34.542a1.634,1.634,0,0,1,1.71-1.492H25.3l1.618-1.244L40.326,21.5a1,1,0,0,1,1.61.792Z"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

2
public/cw_/public/js/axios.min.js 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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
(function(d,e){"object"===typeof exports&&"undefined"!==typeof module?e(exports):"function"===typeof define&&define.amd?define(["exports"],e):(d=d||self,e(d.alawmulaw={}))})(this,function(d){function e(a){a=-32768==a?-32767:a;var c=~a>>8&128;c||(a*=-1);32635<a&&(a=32635);if(256<=a){var b=k[a>>8&127];a=b<<4|a>>b+3&15}else a>>=4;return a^c^85}function f(a){var c=0;a^=85;a&128&&(a&=-129,c=-1);var b=((a&240)>>4)+4;a=4!=b?1<<b|(a&15)<<b-4|1<<b-5:a<<1|1;return-8*(0===c?a:-a)}function g(a){var c=a>>8&128;
0!=c&&(a=-a);a+=132;32635<a&&(a=32635);var b=l[a>>7&255];return~(c|b<<4|a>>b+3&15)}function h(a){a=~a;var c=a>>4&7;c=m[c]+((a&15)<<c+3);0!=(a&128)&&(c=-c);return c}var k=[1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7],n=Object.freeze({__proto__:null,encodeSample:e,decodeSample:f,encode:function(a){for(var c=
new Uint8Array(a.length),b=0;b<a.length;b++)c[b]=e(a[b]);return c},decode:function(a){for(var c=new Int16Array(a.length),b=0;b<a.length;b++)c[b]=f(a[b]);return c}}),l=[0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7],m=[0,132,396,924,1980,4092,8316,16764],p=Object.freeze({__proto__:null,encodeSample:g,decodeSample:h,encode:function(a){for(var c=new Uint8Array(a.length),b=0;b<a.length;b++)c[b]=g(a[b]);return c},decode:function(a){for(var c=new Int16Array(a.length),b=0;b<a.length;b++)c[b]=h(a[b]);return c}});d.alaw=n;d.mulaw=p;Object.defineProperty(d,
"__esModule",{value:!0})});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,234 @@
function CmsTalk() {
this.wasmLoaded = false;
this.logger = new Logger("CmsTalk");
this.urlBufferBuffer = null
this.audioCache = null
this.localAudioStream = null
this.ws = null
this.mediaRecorder = null
this.audioBuffer = null
this.rec = null
// this.recBlob = null;
/**调用open打开录音请求好录音权限**/
this.RecorderOpen()
}
CmsTalk.prototype.RecorderOpen = function () {
//recOpen我们可以选择性的弹一个对话框为了防止移动端浏览器存在第三种情况用户忽略并且或者国产系统UC系浏览器没有任何回调
var showDialog = function () {
if (!/mobile/i.test(navigator.userAgent)) {
return //只在移动端开启没有权限请求的检测
}
dialogCancel()
//显示弹框,应该使用自己的弹框方式
var div = document.createElement("div")
document.body.appendChild(div)
div.innerHTML =
"" +
'<div class="waitDialog" style="z-index:99999;width:100%;height:100%;top:0;left:0;position:fixed;background:rgba(0,0,0,0.3);">' +
'<div style="display:flex;height:100%;align-items:center;">' +
'<div style="flex:1;"></div>' +
'<div style="width:240px;background:#fff;padding:15px 20px;border-radius: 10px;">' +
'<div style="padding-bottom:10px;">录音功能需要麦克风权限,请允许;如果未看到任何请求,请点击忽略~</div>' +
'<div style="text-align:center;"><a onclick="waitDialogClick()" style="color:#0B1">忽略</a></div>' +
"</div>" +
'<div style="flex:1;"></div>' +
"</div>" +
"</div>"
}
var createDelayDialog = function () {
dialogInt = setTimeout(function () {
//定时8秒后打开弹窗用于监测浏览器没有发起权限请求的情况在open前放置定时器利于收到了回调能及时取消不管open是同步还是异步回调的
showDialog()
}, 8000)
}
var dialogInt
var dialogCancel = function () {
clearTimeout(dialogInt)
//关闭弹框,应该使用自己的弹框方式
var elems = document.querySelectorAll(".waitDialog")
for (var i = 0; i < elems.length; i++) {
elems[i].parentNode.removeChild(elems[i])
}
}
//recOpen弹框End
var formatMs = function (ms, all) {
var f = Math.floor(ms / 60000),
m = Math.floor(ms / 1000) % 60
var s =
(all || f > 0 ? (f < 10 ? "0" : "") + f + ":" : "") +
(all || f > 0 || m > 0 ? ("0" + m).substr(-2) + "″" : "") +
("00" + (ms % 1000)).substr(-3)
return s
}
// var recOpen = function () {//一般在显示出录音按钮或相关的录音界面时进行此方法调用,后面用户点击开始录音时就能畅通无阻了
this.newRec = Recorder({
type: "pcm", sampleRate: 8000, bitRate: 16 //mp3格式指定采样率hz、比特率kbps其他参数使用默认配置注意是数字的参数必须提供数字不要用字符串需要使用的type类型需提前把格式支持文件加载进来比如使用wav格式需要提前加载wav.js编码引擎
, onProcess: function (buffers, powerLevel, bufferDuration, bufferSampleRate, newBufferIdx, asyncEnd) {
newBufferIdx = 0
var newChunkInfo = Recorder.SampleData(buffers, 48000, 8000, this.prevChunkInfo);
this.sendAudioData(newChunkInfo.data)
this.prevChunkInfo = newChunkInfo
for (let index = buffers.length - 1; index >= 0; index--) {
buffers[index] = null;
}
}.bind(this)
});
// createDelayDialog(); //我们可以选择性的弹一个对话框为了防止移动端浏览器存在第三种情况用户忽略并且或者国产系统UC系浏览器没有任何回调此处demo省略了弹窗的代码
window.waitDialogClick = function () {
dialogCancel();
console.log("打开失败:权限请求被忽略,<span style='color:#f00'>用户主动点击的弹窗</span>", 1);
};
// };
}
//打开麦克风授权获得相关资源
CmsTalk.prototype.open = function (callback) {
// dialogCancel(); //如果开启了弹框,此处需要取消
if (this.rec){
console.log("已打开录音设备,可以点击录制开始录音了", 2);
callback(null)
return
}
this.newRec.open(function () {
this.rec = this.newRec;
console.log("已打开录音设备,可以点击录制开始录音了", 2);
callback()
}.bind(this), function (msg, isUserNotAllow) {
//用户拒绝未授权或不支持
// dialogCancel(); //如果开启了弹框,此处需要取消
var log = (isUserNotAllow ? "UserNotAllow" : "") + "打开录音失败:" + msg;
console.log(log);
callback(log)
})
}
/**关闭录音,释放资源**/
CmsTalk.prototype.recClose = function () {
if (this.rec) {
this.rec.close();
this.rec = null
console.log("已关闭");
} else {
console.log("未打开录音", 1);
};
};
/**开始录音**/
CmsTalk.prototype.recStart = function () {//打开了录音后才能进行start、stop调用
this.prevChunkInfo = null
if (this.rec && Recorder.IsOpen()) {
// this.recBlob = null;
this.rec.start();
console.log("已开始录音...");
} else {
console.log("未打开录音", 1);
};
};
/**暂停录音**/
CmsTalk.prototype.recPause = function () {
if (this.rec && Recorder.IsOpen()) {
this.rec.pause();
} else {
console.log("未打开录音", 1);
};
};
/**恢复录音**/
CmsTalk.prototype.recResume = function () {
if (this.rec && Recorder.IsOpen()) {
this.rec.resume();
} else {
console.log("未打开录音", 1);
};
};
/**结束录音,得到音频文件**/
CmsTalk.prototype.recStop = function () {
if (!(this.rec && Recorder.IsOpen())) {
console.log("未打开录音", 1);
return;
};
this.rec.stop(null, null);
};
CmsTalk.prototype.startTalk = function (url, callback) {
this.open((err) => {
if (err) {
callback(err)
} else {
if (url.indexOf("http") != -1) {
//方式1,可手动修改talk-server对应的地址
this.ws = new WebSocket("ws://192.168.0.215:3000");
this.ws.onmessage = function (msg) {
console.log(msg);
};
this.ws.onopen = (ev) => {
console.log("open")
this.ws.send(url)
this.recStart()
if (callback)
callback(null)
}
}
else {
//方式2
this.ws = new WebSocket(url);
this.ws.onmessage = function (msg) {
console.log(msg);
};
this.ws.onopen = (ev) => {
console.log("open")
this.recStart()
if (callback)
callback(null)
}
}
}
})
}
CmsTalk.prototype.stopTalk = function () {
if (this.ws) {
this.ws.close();
this.ws = null
}
if (this.audioBuffer) {
delete this.audioBuffer
this.audioBuffer = null
}
this.recStop()
// this.recClose()
}
CmsTalk.prototype.sendAudioData = function (samples) {
var u8Data = alawmulaw.alaw.encode(samples);
if (!this.audioBuffer)
this.audioBuffer = new Uint8Array([])
var tmpBuffer = new Uint8Array(this.audioBuffer.byteLength + u8Data.byteLength)
tmpBuffer.set(this.audioBuffer, 0)
tmpBuffer.set(u8Data, this.audioBuffer.byteLength)
while (tmpBuffer.byteLength >= 480) {
var d480 = tmpBuffer.subarray(0, 480);
tmpBuffer = tmpBuffer.subarray(480);
console.log("reserve ", tmpBuffer.length)
if (this.ws)
this.ws.send(d480)
}
this.audioBuffer = tmpBuffer
}

View File

@ -0,0 +1,51 @@
//Player request.
const kCloseDecoderReq = 0;
const kOpenDecoderReq = 1;
const kRequestHeaderReq = 2;
const kRequestBodyReq = 3;
const kPauseGetUrlReq = 4;
const kResumeGetUrlReq = 5;
const kRequestLiveReq = 6;
const kDecodeVideo = 7;
//CMSParser response.
const kCMSHeaderRes = 8;
const kVideoFrame = 9;
const kAudioFrame = 10;
const kImageFrame = 11;
const kFinishDownload = 12;
const kVideoBuffer = 13;
const kCmsPartHeader = 14;
function Logger(module) {
this.module = module;
}
Logger.prototype.log = function (line) {
console.log("[" + this.currentTimeStr() + "][" + this.module + "]" + line);
}
Logger.prototype.logError = function (line) {
// console.log("[" + this.currentTimeStr() + "][" + this.module + "][ER] " + line);
}
Logger.prototype.logInfo = function (line) {
// console.log("[" + this.currentTimeStr() + "][" + this.module + "][IF] " + line);
}
Logger.prototype.logDebug = function (line) {
// console.log("[" + this.currentTimeStr() + "][" + this.module + "][DT] " + line);
}
Logger.prototype.currentTimeStr = function () {
var now = new Date(Date.now());
var year = now.getFullYear();
var month = now.getMonth() + 1;
var day = now.getDate();
var hour = now.getHours();
var min = now.getMinutes();
var sec = now.getSeconds();
var ms = now.getMilliseconds();
return year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec + ":" + ms;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,14 @@
prefix=/home/weixin/player3/ffmpeg/../WasmVideoPlayer-master/dist
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: libavcodec
Description: FFmpeg codec library
Version: 57.89.100
Requires: libavutil >= 55.58.100
Requires.private:
Conflicts:
Libs: -L${libdir} -lavcodec -s USE_SDL=2 -lm -pthreads
Libs.private:
Cflags: -I${includedir}

View File

@ -0,0 +1,14 @@
prefix=/home/weixin/player3/ffmpeg/../WasmVideoPlayer-master/dist
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: libavformat
Description: FFmpeg container format library
Version: 57.71.100
Requires: libavcodec >= 57.89.100, libavutil >= 55.58.100
Requires.private:
Conflicts:
Libs: -L${libdir} -lavformat -s USE_SDL=2 -lm -pthreads
Libs.private:
Cflags: -I${includedir}

View File

@ -0,0 +1,14 @@
prefix=/home/weixin/player3/ffmpeg/../WasmVideoPlayer-master/dist
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: libavutil
Description: FFmpeg utility library
Version: 55.58.100
Requires:
Requires.private:
Conflicts:
Libs: -L${libdir} -lavutil -lm
Libs.private:
Cflags: -I${includedir}

View File

@ -0,0 +1,14 @@
prefix=/home/weixin/player3/ffmpeg/../WasmVideoPlayer-master/dist
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: libswresample
Description: FFmpeg audio resampling library
Version: 2.7.100
Requires: libavutil >= 55.58.100
Requires.private:
Conflicts:
Libs: -L${libdir} -lswresample -lm
Libs.private:
Cflags: -I${includedir}

View File

@ -0,0 +1,14 @@
prefix=/home/weixin/player3/ffmpeg/../WasmVideoPlayer-master/dist
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: libswscale
Description: FFmpeg image rescaling library
Version: 4.6.100
Requires: libavutil >= 55.58.100
Requires.private:
Conflicts:
Libs: -L${libdir} -lswscale -lm
Libs.private:
Cflags: -I${includedir}

View File

@ -0,0 +1,377 @@
function CmsParser() {
this.CMS_FLAG_FORMAT_FOUND = 0x01;
this.CMS_FLAG_TRACK_FOUND = 0x02;
this.CMS_FLAG_STOP_WHEN_ERROR = 0x04;
this.CMS_PART_UNKNOWN = 'na';
this.CMS_PART_H264_i_FRAME = 'i';
this.CMS_PART_H264_p_FRAME = 'p';
this.CMS_PART_AUDIO = 'a';
this.CMS_PART_JPG = 'j';
this.CMS_E_HEADER_FIELD = 0;
this.CMS_E_HEADER_END = 1;
this.CMS_E_PART_HEADER = 2;
this.CMS_E_PART_HEADER_FIELD = 3;
this.CMS_E_PART_HEADER_END = 4;
this.CMS_E_PART_END = 5;
this.CMS_E_CHUNK = 6;
this.CMS_E_PARSE_FAIL = 7;
this.CMS_HEADER = 0;
this.CMS_DETECT_BOUNDARY = 1;
this.CMS_PART_HEADER = 2;
this.CMS_FINISHED = 3;
this.CMS_FAIL = 4;
this.flag = 0;
this.shift = 0;
this.line_buf = new Uint8Array(2000);
this.line_buf_ptr = 0;
this.state = this.CMS_HEADER;
this.cache = new Uint8Array(100); // for boundary
this.cached_len = 0;
this.is_first_part = true;
this.callback_context = null;
this.callback = null;
this.boundary = null;
this.boundary_size = 0;
this.boundary_ptr = 0;
// boundary = strdup("\r\n----asdfasdf\r\n");
// boundary.length = strlen(boundary);
this._header = {
hasAudio: false,
hasVideo: false
};
this.parts = [];
this.part = {
header: {},
shift: 0,
chunks: []
};
};
CmsParser.prototype.fail = function (error) {
this.emit(this.CMS_E_PARSE_FAIL, error);
if (this.flag & this.CMS_FLAG_STOP_WHEN_ERROR) {
this.state = this.CMS_FAIL;
return true;
} else {
this.state = this.CMS_DETECT_BOUNDARY;
return false;
}
}
CmsParser.prototype.parse = function (data) {
var chunk = 0;
for (var i = 0; i < data.length; i++) {
var ch = data[i];
ch = String.fromCharCode(ch);
this.shift++;
switch (this.state) {
case this.CMS_FAIL: {
if (this.fail("CmsParser parse stoped.")) {
return;
}
break;
};
case this.CMS_HEADER: {
if (ch === '\r') {
} else if (ch === '\n') {
if (this.line_buf_ptr === 0) {
this.emit(this.CMS_E_HEADER_END);
if (!this.boundary) {
if (this.fail("Boundary not found.")) {
return;
}
} else if (!(this.flag & this.CMS_FLAG_FORMAT_FOUND)) {
if (this.fail("Format not found.")) {
return;
}
} else if (!(this.flag & this.CMS_FLAG_TRACK_FOUND)) {
if (this.fail("Track not found.")) {
return;
}
} else {
this.state = this.CMS_DETECT_BOUNDARY;
this.boundary_ptr = 2;
chunk = i + 1;
}
} else {
var s = String.fromCharCode.apply(null, this.line_buf.slice(0, this.line_buf_ptr));
s = s.split(":");
var key = s.shift().trim();
var value = s.join(":").trim();
// console.log("cms header:", key, '=', value);
if (key && value) {
if (key === "boundary") {
this.boundary = "\r\n--" + value + "\r\n";
} else if (key === "format" && value === "cms") {
this.flag = this.flag | this.CMS_FLAG_FORMAT_FOUND;
} else if (key === "track") {
this.flag = this.flag | this.CMS_FLAG_TRACK_FOUND;
}
var kv = {
key: key,
value: value
};
this.emit(this.CMS_E_HEADER_FIELD, kv);
} else {
if (this.fail("Invalid key value.")) {
return;
}
}
}
this.line_buf_ptr = 0;
this.line_buf.fill(0);
} else {
this.line_buf[this.line_buf_ptr] = ch.charCodeAt(0);
this.line_buf_ptr++;
}
break;
};
case this.CMS_DETECT_BOUNDARY: {
if (!this.boundary) {
break;
}
if (ch == this.boundary[this.boundary_ptr]) {
this.boundary_ptr++;
} else if (this.boundary_ptr == 1 && ch == this.boundary[this.boundary_ptr - 1]) {
} else {
if (this.cached_len > 0) {
this.emit(this.CMS_E_CHUNK, this.cache.slice(0, this.cached_len));
this.cached_len = 0;
}
this.boundary_ptr = 0;
}
if (this.boundary_ptr === this.boundary.length) {
if (i - chunk >= (this.boundary.length - this.cached_len)) {
var chunk_len = i - chunk - (this.boundary.length - this.cached_len) + 1;
this.emit(this.CMS_E_CHUNK, data.slice(chunk, chunk + chunk_len));
}
this.cached_len = 0;
if (this.is_first_part) {
this.is_first_part = false;
} else {
this.emit(this.CMS_E_PART_END);
}
this.emit(this.CMS_E_PART_HEADER);
this.state = this.CMS_PART_HEADER;
this.part = {
header: {
type: this.CMS_PART_UNKNOWN,
track: -1,
length: 0,
ts: -1
},
shift: this.shift,
chunks: []
}
chunk = i + 1;
this.boundary_ptr = 0;
this.line_buf_ptr = 0;
this.line_buf[0] = 0;
}
break;
};
case this.CMS_PART_HEADER: {
if (ch == '\r') {
} else if (ch == '\n') {
if (this.line_buf_ptr == 0) {
this.emit(this.CMS_E_PART_HEADER_END);
this.state = this.CMS_DETECT_BOUNDARY;
chunk = i + 1;
} else {
var s = String.fromCharCode.apply(null, this.line_buf.slice(0, this.line_buf_ptr)).split(":");
var key = s.shift().trim();
var value = s.join(":").trim();
// console.log("part header:", key, '=', value);
if (key && value) {
if (key === "f") {
if (value === "i") {
this.part.header.type = this.CMS_PART_H264_i_FRAME;
} else if (value === "p") {
this.part.header.type = this.CMS_PART_H264_p_FRAME;
} else if (value === "a") {
this.part.header.type = this.CMS_PART_AUDIO;
} else if (value === "j") {
this.part.header.type = this.CMS_PART_JPG;
} else {
console.error("Unknown frame type:", value);
}
} else if (key === "ts") {
this.part.header.ts = parseInt(value, 10);
} else if (key === "l") {
this.part.header.length = parseInt(value, 10);
} else if (key === "t") {
this.part.header.track = parseInt(value, 10);
}
var kv = {
key: key,
value: value
};
this.emit(this.CMS_E_PART_HEADER_FIELD, kv);
} else {
if (this.fail("Part header Invalid key value.")) {
return;
}
}
}
this.line_buf_ptr = 0;
this.line_buf.fill(0);
} else {
if (this.line_buf_ptr < this.line_buf.length - 1) {
this.line_buf[this.line_buf_ptr] = ch.charCodeAt(0);
this.line_buf_ptr++;
} else {
if (this.fail("Part header line too long.")) {
return;
}
}
}
break;
};
}
}
if (this.state == this.CMS_DETECT_BOUNDARY) {
if (chunk < data.length) {
if (this.boundary_ptr > 0) {
this.cached_len = this.boundary_ptr;
var pos = data.length - this.boundary_ptr;
if (pos >= 0) {
this.cache = data.slice(pos, this.cached_len);
}
}
this.emit(this.CMS_E_CHUNK, data.slice(chunk, chunk + data.length - chunk - this.boundary_ptr));
}
}
};
CmsParser.prototype.set_callback = function (cb, context) {
this.callback = cb;
this.callback_context = context;
};
CmsParser.prototype.emit = function (e, data, size) {
if (this.callback) {
return this.callback(this, e, data, size, this.callback_context);
} else {
this.cache_data(e, data);
}
};
CmsParser.prototype.cache_data = function (e, data) {
switch (e) {
case this.CMS_E_HEADER_FIELD: {
var key = data.key;
var value = data.value;
this._header[key] = value;
if (key === 'track') {
var tracks = value.split(';');
this._header.tracks = [];
for (var t = 0; t < tracks.length; t++) {
var fields = tracks[t].split(',');
var track = {};
for (var j = 0; j < fields.length; j++) {
var f = fields[j].split('=');
var key = f.shift();
var value = f.join('=');
track[key] = value;
if (key === 'codec') {
if (value === 'alaw') {
this._header.hasAudio = true;
this._header.audioTrack = track;
} else if (value === 'h264') {
this._header.hasVideo = true;
this._header.videoTrack = track;
}
}
}
this._header.tracks.push(track);
}
} else if (key === "duration") {
this._header.duration = parseInt(value, 10);
}
break;
};
case this.CMS_E_HEADER_END: {
this.header = this._header;
break;
};
case this.CMS_E_PART_HEADER: {
break;
};
case this.CMS_E_PART_HEADER_FIELD: {
break;
};
case this.CMS_E_PART_HEADER_END: {
break;
};
case this.CMS_E_PART_END: {
var chunks = this.part.chunks;
var size = 0;
for (var i = 0; i < chunks.length; i++) {
size = size + chunks[i].length;
}
this.part.data = new ArrayBuffer(size);
var data = new Uint8Array(this.part.data);
var shift = 0;
for (var i = 0; i < chunks.length; i++) {
data.set(chunks[i], shift);
shift = shift + chunks[i].length;
}
this.parts.push(this.part);
break;
};
case this.CMS_E_CHUNK: {
this.part.chunks.push(data);
break;
};
case this.CMS_E_PARSE_FAIL: {
break;
};
}
};
module.exports = CmsParser;
// var cms = new CmsParser();
// var fs = require('fs');
// var f = fs.createReadStream("/home/gxy/work/cms/cms/tmp/ttt.cms");
// f.on('end', function (err) {
// console.log("end");
// });
// f.on('error', function (err) {
// console.error(err);
// });
// f.on('data', function (chunk) {
// cms.parse(chunk);
// if (cms.header) {
// console.log(cms.header);
// cms.header = null;
// }
// var parts = cms.parts;
// while (parts.length > 0) {
// var part = parts.shift();
// console.log(part.header);
// var chunks = part.chunks;
// var len = 0;
// for (var i = 0; i < chunks.length; i++) {
// len = len + chunks[i].length;
// }
// if (len !== part.header.length) {
// console.log("mismatch: len=%d part.len=%d", len, part.header.length);
// }
// }
// });

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1,204 @@
function PCMPlayer(option) {
console.log("PCMPlayer new")
this.init(option);
}
PCMPlayer.prototype.init = function (option) {
var defaults = {
encoding: '16bitInt',
channels: 1,
sampleRate: 8000,
flushingTime: 1000
};
this.option = Object.assign({}, defaults, option);
this.samples = new Float32Array();
this.flush = this.flush.bind(this);
this.interval = setInterval(this.flush, this.option.flushingTime);
this.maxValue = this.getMaxValue();
this.typedArray = this.getTypedArray();
this.createContext();
this.lastBufferSource = null
};
PCMPlayer.prototype.getMaxValue = function () {
var encodings = {
'8bitInt': 128,
'16bitInt': 32768,
'32bitInt': 2147483648,
'32bitFloat': 1
}
return encodings[this.option.encoding] ? encodings[this.option.encoding] : encodings['16bitInt'];
};
PCMPlayer.prototype.getTypedArray = function () {
var typedArrays = {
'8bitInt': Int8Array,
'16bitInt': Int16Array,
'32bitInt': Int32Array,
'32bitFloat': Float32Array
}
return typedArrays[this.option.encoding] ? typedArrays[this.option.encoding] : typedArrays['16bitInt'];
};
PCMPlayer.prototype.createContext = function () {
this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();
this.gainNode = this.audioCtx.createGain();
this.gainNode.gain.value = 1;
this.gainNode.connect(this.audioCtx.destination);
this.startTime = this.audioCtx.currentTime;
};
PCMPlayer.prototype.isTypedArray = function (data) {
return (data.byteLength && data.buffer && data.buffer.constructor == ArrayBuffer);
};
PCMPlayer.prototype.feed = function (data) {
if (!this.isTypedArray(data)) return;
data = this.getFormatedValue(data);
var tmp = new Float32Array(this.samples.length + data.length);
tmp.set(this.samples, 0);
tmp.set(data, this.samples.length);
this.samples = tmp;
};
PCMPlayer.prototype.getFormatedValue = function (data) {
var data = new this.typedArray(data.buffer),
float32 = new Float32Array(data.length),
i;
for (i = 0; i < data.length; i++) {
float32[i] = data[i] / this.maxValue;
}
return float32;
};
PCMPlayer.prototype.volume = function (volume) {
this.gainNode.gain.value = volume;
};
PCMPlayer.prototype.destroy = function () {
console.log("PCMPlayer destroy")
if (this.interval) {
clearInterval(this.interval);
}
this.samples = null;
this.audioCtx.close();
this.audioCtx = null;
};
PCMPlayer.prototype.flush = function () {
// console.log("PCMPlayer.prototype.flush", this.samples.length)
if (!this.samples.length) return;
var bufferSource = this.audioCtx.createBufferSource(),
length = this.samples.length / this.option.channels,
audioBuffer = this.audioCtx.createBuffer(this.option.channels, length, this.option.sampleRate),
audioData,
channel,
offset,
i,
decrement;
for (channel = 0; channel < this.option.channels; channel++) {
audioData = audioBuffer.getChannelData(channel);
offset = channel;
decrement = 50;
for (i = 0; i < length; i++) {
audioData[i] = this.samples[offset];
/* fadein */
if (i < 50) {
audioData[i] = (audioData[i] * i) / 50;
}
/* fadeout*/
if (i >= (length - 51)) {
audioData[i] = (audioData[i] * decrement--) / 50;
}
offset += this.option.channels;
}
}
if (this.startTime < this.audioCtx.currentTime) {
this.startTime = this.audioCtx.currentTime;
}
// console.log('start vs current '+this.startTime+' vs '+this.audioCtx.currentTime+' duration: '+audioBuffer.duration);
bufferSource.buffer = audioBuffer;
bufferSource.connect(this.gainNode);
bufferSource.start(this.startTime);
this.startTime += audioBuffer.duration;
this.samples = new Float32Array();
};
PCMPlayer.prototype.getTimestamp = function () {
if (this.audioCtx) {
return this.audioCtx.currentTime;
} else {
return 0;
}
};
PCMPlayer.prototype.play = function (data, flushcache) {
if (!this.isTypedArray(data)) {
return;
}
if (this.audioCtx.state === 'suspended') {
return;
}
data = this.getFormatedValue(data);
if (!data.length) {
return;
}
var bufferSource = this.audioCtx.createBufferSource();
var length = data.length / this.option.channels;
var audioBuffer = this.audioCtx.createBuffer(this.option.channels, length, this.option.sampleRate);
var audioData, channel, offset, i, decrement;
for (channel = 0; channel < this.option.channels; channel++) {
audioData = audioBuffer.getChannelData(channel);
offset = channel;
decrement = 50;
for (i = 0; i < length; i++) {
audioData[i] = data[offset];
/* fadein */
if (i < 50) {
audioData[i] = (audioData[i] * i) / 50;
}
/* fadeout*/
if (i >= (length - 51)) {
audioData[i] = (audioData[i] * decrement--) / 50;
}
offset += this.option.channels;
}
}
if (this.startTime < this.audioCtx.currentTime) {
this.startTime = this.audioCtx.currentTime;
}
// console.log('start vs current '+this.startTime+' vs '+this.audioCtx.currentTime+' duration: '+audioBuffer.duration);
bufferSource.buffer = audioBuffer;
bufferSource.connect(this.gainNode);
bufferSource.start(this.startTime);
this.startTime += audioBuffer.duration - 0.008;
// bufferSource.playbackRate(1.05)
this.lastBufferSource = bufferSource
};
PCMPlayer.prototype.pause = function () {
if (this.audioCtx.state === 'running') {
this.audioCtx.suspend()
}
}
PCMPlayer.prototype.resume = function () {
if (this.audioCtx.state === 'suspended') {
this.audioCtx.resume()
}
}
PCMPlayer.prototype.stop = function () {
if (this.lastBufferSource)
this.lastBufferSource.stop()
}

Some files were not shown because too many files have changed in this diff Show More