1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668 |
- <template>
- <view>
- <view class="trtc-room-container">
- <view v-if="template === '1v1'">
- <view data-type="template" data-is="1v1" data-attr="pusher, streamList, debug">
- <view class="template-1v1">
- <view
- v-for="(item, streamID) in streamList"
- :key="streamID"
- v-if="item.src && (item.hasVideo || item.hasAudio)"
- :class="'view-container player-container ' + (item.isVisible ? '' : 'none')"
- >
- <live-player
- class="player"
- :data-userid="item.userID"
- :data-streamid="item.streamID"
- :data-streamtype="item.streamType"
- :src="item.src"
- mode="RTC"
- :autoplay="item.autoplay"
- :mute-audio="item.muteAudio"
- :mute-video="item.muteVideo"
- :orientation="item.orientation"
- :object-fit="item.objectFit"
- :background-mute="item.enableBackgroundMute"
- :min-cache="item.minCache"
- :max-cache="item.maxCache"
- :sound-mode="item.soundMode"
- :enable-recv-message="item.enableRecvMessage"
- :auto-pause-if-navigate="item.autoPauseIfNavigate"
- :auto-pause-if-open-native="item.autoPauseIfOpenNative"
- :debug="debug"
- @statechange="playerStateChangeFun"
- @fullscreenchange="playerFullscreenChangeFun"
- @netstatus="playerNetStatusFun"
- @audiovolumenotify="playerAudioVolumeNotifyFun"
- :idAttr="item.streamID"
- ></live-player>
- </view>
- <view style="display:none" :class="'view-container pusher-container ' + (pusher.isVisible ? '' : 'none') + ' ' + (JSON.stringify(streamList) == '[]' ? 'fullscreen' : '')">
- <live-pusher
- class="pusher"
- :url="pusher.url"
- :mode="pusher.mode"
- :autopush="pusher.autopush"
- :enable-camera="pusher.enableCamera"
- :enable-mic="pusher.enableMic"
- :enable-agc="pusher.enableAgc"
- :enable-ans="pusher.enableAns"
- :enable-ear-monitor="pusher.enableEarMonitor"
- :auto-focus="pusher.enableAutoFocus"
- :zoom="pusher.enableZoom"
- :min-bitrate="pusher.minBitrate"
- :max-bitrate="pusher.maxBitrate"
- :video-width="pusher.videoWidth"
- :video-height="pusher.videoHeight"
- :beauty="pusher.beautyLevel"
- :whiteness="pusher.whitenessLevel"
- :orientation="pusher.videoOrientation"
- :aspect="pusher.videoAspect"
- :device-position="pusher.frontCamera"
- :remote-mirror="pusher.enableRemoteMirror"
- :local-mirror="pusher.localMirror"
- :background-mute="pusher.enableBackgroundMute"
- :audio-quality="pusher.audioQuality"
- :audio-volume-type="pusher.audioVolumeType"
- :audio-reverb-type="pusher.audioReverbType"
- :waiting-image="pusher.waitingImage"
- :debug="debug"
- @statechange="pusherStateChangeHandlerFun"
- @netstatus="pusherNetStatusHandlerFun"
- @error="pusherErrorHandlerFun"
- @bgmstart="pusherBGMStartHandlerFun"
- @bgmprogress="pusherBGMProgressHandlerFun"
- @bgmcomplete="pusherBGMCompleteHandlerFun"
- ></live-pusher>
- <view class="loading" v-if="streamList.length === 0">
- <!-- <view class="loading-img"><image src="../../static/components/trtc-room/static/loading.png" class="rotate-img"></image></view> -->
- <view class="loading-text">等待接听中...</view>
- </view>
- </view>
- <view class="handle-btns">
- <view class="btn-normal" @tap="toggleAudioFun">
- <image
- :src="pusher.enableMic ? '../../static/components/trtc-room/static/audio-true.png' : '../../static/components/trtc-room/static/audio-false.png'"
- ></image>
- </view>
- <!-- <view class="btn-normal" @tap="switchCamera"><image src="../../static/components/trtc-room/static/switch.png"></image></view> -->
- <!-- <view class="btn-normal" bindtap="toggleVideoFun">
- <image src="{{pusher.enableCamera? '../../static/components/trtc-room/static/camera-true.png': '../../static/components/trtc-room/static/camera-false.png'}} "></image>
- </view> -->
- <view class="btn-normal" @tap="toggleSoundModeFun">
- <image
- :src="
- streamList[0].soundMode === 'ear'
- ? '../../static/components/trtc-room/static/phone.png'
- : '../../static/components/trtc-room/static/speaker-true.png'
- "
- ></image>
- </view>
- </view>
- <view class="bottom-btns">
- <!-- <view class="btn-hangup" @tap="hangUpFun"><image src="../../static/components/trtc-room/static/hangup.png"></image></view> -->
- </view>
- </view>
- </view>
- </view>
- <view v-if="template === 'grid'">
- <view style="background: #000" data-type="template" data-is="grid" data-attr="pusher, streamList, debug, panelName">
- <view :class="'template-grid ' + (streamList.length < 6 ? 'stream-' + streamList.length : 'stream-5')">
- <view
- v-for="(item, streamID) in streamList"
- :key="streamID"
- v-if="item.src && (item.hasVideo || item.hasAudio)"
- :class="'view-container player-container ' + (item.isVisible ? '' : 'none')"
- :data-userid="item.userID"
- :data-streamtype="item.streamType"
- @tap="doubleTabToggleFullscreenFun"
- >
- <live-player
- class="player"
- :data-userid="item.userID"
- :data-streamid="item.streamID"
- :data-streamtype="item.streamType"
- :src="item.src"
- mode="RTC"
- :autoplay="item.autoplay"
- :mute-audio="item.muteAudio"
- :mute-video="item.muteVideo"
- :orientation="item.orientation"
- :object-fit="item.objectFit"
- :background-mute="item.enableBackgroundMute"
- :min-cache="item.minCache"
- :max-cache="item.maxCache"
- :sound-mode="item.soundMode"
- :enable-recv-message="item.enableRecvMessage"
- :auto-pause-if-navigate="item.autoPauseIfNavigate"
- :auto-pause-if-open-native="item.autoPauseIfOpenNative"
- :debug="debug"
- @statechange="playerStateChangeFun"
- @fullscreenchange="playerFullscreenChangeFun"
- @netstatus="playerNetStatusFun"
- @audiovolumenotify="playerAudioVolumeNotifyFun"
- :idAttr="item.streamID"
- ></live-player>
- <view class="operation-bar">
- <view class="btn-normal" @tap="handleSubscribeRemoteAudioFun" :data-user-i-d="item.userID" :data-stream-type="item.streamType">
- <image
- :src="
- item.muteAudio
- ? '../../static/components/trtc-room/static/speaker-false.png'
- : '../../static/components/trtc-room/static/speaker-true.png'
- "
- ></image>
- </view>
- <view class="btn-normal" @tap="handleSubscribeRemoteVideoFun" :data-user-i-d="item.userID" :data-stream-type="item.streamType">
- <image
- :src="
- item.muteVideo
- ? '../../static/components/trtc-room/static/camera-false.png'
- : '../../static/components/trtc-room/static/camera-true.png'
- "
- ></image>
- </view>
- <view class="btn-normal" @tap="toggleFullscreenFun" :data-user-i-d="item.userID" :data-stream-type="item.streamType">
- <!-- <image src="../../static/components/trtc-room/static/fullscreen.png"></image> -->
- </view>
- </view>
- <progress class="volume-progress" :percent="item.volume" stroke-width="4"></progress>
- </view>
- <view style="display:none" :class="'view-container pusher-container ' + (pusher.isVisible ? '' : 'none')">
- <live-pusher
- class="pusher"
- :url="pusher.url"
- :mode="pusher.mode"
- :autopush="pusher.autopush"
- :enable-camera="pusher.enableCamera"
- :enable-mic="pusher.enableMic"
- :enable-agc="pusher.enableAgc"
- :enable-ans="pusher.enableAns"
- :enable-ear-monitor="pusher.enableEarMonitor"
- :auto-focus="pusher.enableAutoFocus"
- :zoom="pusher.enableZoom"
- :min-bitrate="pusher.minBitrate"
- :max-bitrate="pusher.maxBitrate"
- :video-width="pusher.videoWidth"
- :video-height="pusher.videoHeight"
- :beauty="pusher.beautyLevel"
- :whiteness="pusher.whitenessLevel"
- :orientation="pusher.videoOrientation"
- :aspect="pusher.videoAspect"
- :device-position="pusher.frontCamera"
- :remote-mirror="pusher.enableRemoteMirror"
- :local-mirror="pusher.localMirror"
- :background-mute="pusher.enableBackgroundMute"
- :audio-quality="pusher.audioQuality"
- :audio-volume-type="pusher.audioVolumeType"
- :audio-reverb-type="pusher.audioReverbType"
- :waiting-image="pusher.waitingImage"
- :debug="debug"
- @statechange="pusherStateChangeHandlerFun"
- @netstatus="pusherNetStatusHandlerFun"
- @error="pusherErrorHandlerFun"
- @bgmstart="pusherBGMStartHandlerFun"
- @bgmprogress="pusherBGMProgressHandlerFun"
- @bgmcomplete="pusherBGMCompleteHandlerFun"
- ></live-pusher>
- <view class="operation-bar">
- <view class="btn-normal" @tap="switchMemberListPanelFun"><i<!-- mage src="../../static/components/trtc-room/static/list.png"></image></view>
- <view class="btn-normal" @tap="switchSettingPanelFun"><image src="../../static/components/trtc-room/static/setting.png"></image></view>
- <view class="btn-normal btn-hangup" @tap="hangUpFun"><image --> src="../../static/components/trtc-room/static/hangup.png"></image></view>
- </view>
- </view>
- <view :class="'panel memberlist-panel ' + (panelName === 'memberlist-panel' ? '' : 'none')">
- <view @tap="handleMaskerClickFun" class="close-btn">X</view>
- <view class="panel-header">成员列表</view>
- <view class="panel-body">
- <view class="panel-tips" v-if="streamList.length === 0">暂无成员</view>
- <scroll-view class="scroll-container" scroll-y="true">
- <view class="member-item" v-for="(item, streamID) in streamList" :key="streamID">
- <view class="member-id">{{ item.userID }}</view>
- <view class="member-btns">
- <button
- class="btn"
- hover-class="btn-hover"
- :data-userid="item.userID"
- :data-streamtype="item.streamType"
- data-key="objectFit"
- data-value="fillCrop|contain"
- @tap="setPlayerPropertyFun"
- >
- {{ item.objectFit === 'fillCrop' ? '填充' : '适应' }}
- </button>
- <button
- class="btn"
- hover-class="btn-hover"
- :data-userid="item.userID"
- :data-streamtype="item.streamType"
- data-key="orientation"
- data-value="vertical|horizontal"
- @tap="setPlayerPropertyFun"
- >
- {{ item.orientation === 'vertical' ? '竖屏' : '横屏' }}
- </button>
- <button
- class="btn"
- hover-class="btn-hover"
- :data-userid="item.userID"
- :data-streamtype="item.streamType"
- @tap="switchStreamTypeFun"
- v-if="item.streamType === 'main'"
- >
- {{ item._definitionType === 'small' ? '小画面' : '主画面' }}
- </button>
- <button class="btn" hover-class="btn-hover" :data-userid="item.userID" :data-streamtype="item.streamType" @tap="handleSnapshotClickFun">
- 截屏
- </button>
- </view>
- </view>
- </scroll-view>
- </view>
- </view>
- <view :class="'panel setting-panel ' + (panelName === 'setting-panel' ? '' : 'none')">
- <view @tap="handleMaskerClickFun" class="close-btn">X</view>
- <view class="panel-header">推流设置</view>
- <view class="panel-body">
- <scroll-view class="scroll-container" scroll-y="true">
- <view class="setting-option">
- <view class="label">启用摄像头</view>
- <view class="btn-normal" @tap="toggleVideoFun">
- <image
- :src="
- pusher.enableCamera
- ? '../../static/components/trtc-room/static/camera-true.png'
- : '../../static/components/trtc-room/static/camera-false.png'
- "
- ></image>
- </view>
- </view>
- <view class="setting-option">
- <view class="label">启用麦克风</view>
- <view class="btn-normal" @tap="toggleAudioFun">
- <image
- :src="
- pusher.enableMic
- ? '../../static/components/trtc-room/static/audio-true.png'
- : '../../static/components/trtc-room/static/audio-false.png'
- "
- ></image>
- </view>
- </view>
- <view class="setting-option">
- <view class="label">切换摄像头</view>
- <!-- <view class="btn-normal" @tap="switchCamera"><image src="../../static/components/trtc-room/static/switch.png"></image></view> -->
- </view>
- <view class="setting-option">
- <view class="label">开启美颜</view>
- <switch
- color="#006eff"
- :checked="pusher.beautyLevel == 9 ? true : false"
- data-key="beautyLevel"
- data-value="9|0"
- @change="setPuserPropertyFun"
- ></switch>
- </view>
- <view class="setting-option">
- <view class="label">开启AGC</view>
- <switch color="#006eff" :checked="pusher.enableAgc" data-key="enableAgc" data-value="true" @change="setPuserPropertyFun"></switch>
- </view>
- <view class="setting-option">
- <view class="label">开启ANS</view>
- <switch color="#006eff" :checked="pusher.enableAns" data-key="enableAns" data-value="true" @change="setPuserPropertyFun"></switch>
- </view>
- <view class="setting-option">
- <view class="label">开启横屏推流</view>
- <switch
- color="#006eff"
- :checked="pusher.videoOrientation === 'vertical' ? false : true"
- data-key="videoOrientation"
- data-value="horizontal|vertical"
- @change="setPuserPropertyFun"
- ></switch>
- </view>
- </scroll-view>
- </view>
- </view>
- <view :class="'masker ' + (panelName == '' ? 'none' : '')" @tap="handleMaskerClickFun"></view>
- </view>
- </view>
- </view>
- <view v-if="template === 'custom'">
- <view data-type="template" data-is="custom" data-attr="pusher, streamList, debug">
- <view class="template-custom">
- <view class="players-container">
- <view
- v-for="(item, streamID) in streamList"
- :key="streamID"
- v-if="item.src && (item.hasVideo || item.hasAudio)"
- :class="'view-container player-container ' + (item.isVisible ? '' : 'none')"
- :style="'left:' + item.xAxis + 'top:' + item.yAxis + 'width:' + item.width + 'height:' + item.height + 'zindex:' + item.zindex + ''"
- >
- <live-player
- class="player"
- :data-userid="item.userID"
- :data-streamid="item.streamID"
- :data-streamtype="item.streamType"
- :src="item.src"
- :mode="item.mode"
- :autoplay="item.autoplay"
- :mute-audio="item.muteAudio"
- :mute-video="item.muteVideo"
- :orientation="item.orientation"
- :object-fit="item.objectFit"
- :background-mute="item.enableBackgroundMute"
- :min-cache="item.minCache"
- :max-cache="item.maxCache"
- :sound-mode="item.soundMode"
- :enable-recv-message="item.enableRecvMessage"
- :auto-pause-if-navigate="item.autoPauseIfNavigate"
- :auto-pause-if-open-native="item.autoPauseIfOpenNative"
- :debug="debug"
- @statechange="playerStateChangeFun"
- @fullscreenchange="playerFullscreenChangeFun"
- @netstatus="playerNetStatusFun"
- @audiovolumenotify="playerAudioVolumeNotifyFun"
- :idAttr="item.streamID"
- ></live-player>
- </view>
- </view>
- <view
- :class="'view-container pusher-container ' + (pusher.isVisible ? '' : 'none')"
- :style="'left:' + pusher.xAxis + 'top:' + pusher.yAxis + 'width:' + pusher.width + 'height:' + pusher.height + 'zindex:' + pusher.zindex + ''"
- >
- <live-pusher
- class="pusher"
- :url="pusher.url"
- :mode="pusher.mode"
- :autopush="pusher.autopush"
- :enable-camera="pusher.enableCamera"
- :enable-mic="pusher.enableMic"
- :enable-agc="pusher.enableAgc"
- :enable-ans="pusher.enableAns"
- :enable-ear-monitor="pusher.enableEarMonitor"
- :auto-focus="pusher.enableAutoFocus"
- :zoom="pusher.enableZoom"
- :min-bitrate="pusher.minBitrate"
- :max-bitrate="pusher.maxBitrate"
- :video-width="pusher.videoWidth"
- :video-height="pusher.videoHeight"
- :beauty="pusher.beautyLevel"
- :whiteness="pusher.whitenessLevel"
- :orientation="pusher.videoOrientation"
- :aspect="pusher.videoAspect"
- :device-position="pusher.frontCamera"
- :remote-mirror="pusher.enableRemoteMirror"
- :local-mirror="pusher.localMirror"
- :background-mute="pusher.enableBackgroundMute"
- :audio-quality="pusher.audioQuality"
- :audio-volume-type="pusher.audioVolumeType"
- :audio-reverb-type="pusher.audioReverbType"
- :waiting-image="pusher.waitingImage"
- :debug="debug"
- @statechange="pusherStateChangeHandlerFun"
- @netstatus="pusherNetStatusHandlerFun"
- @error="pusherErrorHandlerFun"
- @bgmstart="pusherBGMStartHandlerFun"
- @bgmprogress="pusherBGMProgressHandlerFun"
- @bgmcomplete="pusherBGMCompleteHandlerFun"
- ></live-pusher>
- </view>
- </view>
- </view>
- </view>
- <view :class="'debug-info-btn ' + (debugMode && !debugPanel ? '' : 'none')"><button @tap="debugTogglePanelFun" hover-class="button-hover">Debug</button></view>
- <view :class="'debug-info ' + (debugMode && debugPanel ? '' : 'none')">
- <view @tap="debugTogglePanelFun" class="close-btn">X</view>
- <view>appVersion: {{ appVersion }}</view>
- <view>libVersion: {{ libVersion }}</view>
- <view>template: {{ template }}</view>
- <view>
- debug:
- <button :class="debug ? '' : 'false'" @tap="debugToggleVideoDebugFun" hover-class="button-hover">{{ debug }}</button>
- </view>
- <view>userID: {{ pusher.userID }}</view>
- <view>roomID: {{ pusher.roomID }}</view>
- <view>
- camera:
- <button :class="pusher.enableCamera ? '' : 'false'" @tap="toggleVideoFun" hover-class="button-hover">{{ pusher.enableCamera }}</button>
- </view>
- <view>
- mic:
- <button :class="pusher.enableMic ? '' : 'false'" @tap="toggleAudioFun" hover-class="button-hover">{{ pusher.enableMic }}</button>
- </view>
- <view>
- switch camera:
- <button @tap="switchCamera" hover-class="button-hover">{{ cameraPosition || pusher.frontCamera }}</button>
- </view>
- <view>
- Room:
- <button @tap="debugEnterRoomFun" hover-class="button-hover">Enter</button>
- <button @tap="debugExitRoomFun" hover-class="button-hover">Exit</button>
- <button @tap="debugGoBackFun" hover-class="button-hover">Go back</button>
- </view>
- <view>user count: {{ userList.length }}</view>
- <view v-for="(item, userID) in userList" :key="userID">
- {{ item.userID }}|mainV:{{ item.hasMainVideo || false }}|mainA:{{ item.hasMainAudio || false }}|auxV:{{ item.hasAuxVideo || false }}
- </view>
- <view>stream count: {{ streamList.length }}</view>
- <view v-for="(item, streamID) in streamList" :key="streamID">
- {{ item.userID }}|{{ item.streamType }}| SubV:
- <button
- :class="!item.muteVideo ? '' : 'false'"
- @tap="debugToggleRemoteVideoFun"
- hover-class="button-hover"
- :data-user-i-d="item.userID"
- :data-stream-type="item.streamType"
- >
- {{ !item.muteVideo }}
- </button>
- | SubA:
- <button
- :class="!item.muteAudio ? '' : 'false'"
- @tap="debugToggleRemoteAudioFun"
- hover-class="button-hover"
- :data-user-i-d="item.userID"
- :data-stream-type="item.streamType"
- >
- {{ !item.muteAudio }}
- </button>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import { setData } from '@/pagesGood/debug/GenerateTestUserSig';
- import UserController from './controller/user-controller';
- import Pusher from './model/pusher';
- import { EVENT } from './common/constants';
- import TIM from './common/tim-wx';
- import Event from './utils/event';
- import * as ENV from './utils/environment';
- const TAG_NAME = 'TRTC-ROOM';
- const IM_GROUP_TYPE = TIM.TYPES.GRP_CHATROOM // TIM.TYPES.GRP_CHATROOM 体验版IM无数量限制,成员20个, TIM.TYPES.GRP_AVCHATROOM IM体验版最多10个,升级后无限制
- export default {
- data() {
- return {
- pusher: null,
- // debugMode: false, // 是否开启调试模式
- debugPanel: true,
- // 是否打开组件调试面板
- debug: false,
- // 是否打开player pusher 的调试信息
- streamList: [],
- // 用于渲染player列表,存储stram
- userList: [],
- // 扁平化的数据用来返回给用户
- template: '',
- // 不能设置默认值,当默认值和传入组件的值不一致时,iOS渲染失败
- cameraPosition: '',
- panelName: '',
- // 控制面板名称,包括 setting-panel memberlist-panel
- localVolume: 0,
- remoteVolumeList: [],
- appVersion: ENV.APP_VERSION,
- libVersion: ENV.LIB_VERSION,
- debugMode: '',
- enableIM: true, // 用于组件内渲染
- showIMPanel: false,
- exitIMThrottle: false,
- messageContent: '',
- messageList: [], // 仅保留10条消息
- maxMessageListLength: 10,
- messageListScrollTop: 0,
- };
- },
- components: {},
- props: {
- // 必要的初始化参数
- config: {
- type: Object,
- default: () => ({
- sdkAppID: '',
- userID: '',
- userSig: '',
- template: '',
- debugMode: '',
- enableIM: true, // 用于组件内渲染
- showIMPanel: false,
- exitIMThrottle: false,
- messageContent: '',
- messageList: [], // 仅保留10条消息
- maxMessageListLength: 10,
- messageListScrollTop: 0
- })
- }
- },
- watch: {
- streamList(newVal, oldVal){
- console.log('streamList::::::::',newVal, oldVal)
- this.streamList = newVal
- },
- config: {
- handler: function(newVal, oldVal) {
- console.log('watch config');
- this.propertyObserverFun({
- name: 'config',
- newVal,
- oldVal
- });
- },
- deep: true
- }
- },
- created: function() {
- // 在组件实例刚刚被创建时执行
- console.log(TAG_NAME, 'created', ENV);
- },
- beforeMount: function() {
- // 在组件实例进入页面节点树时执行
- console.log(TAG_NAME, 'attached');
- this.initFun();
- },
- mounted: function() {
- // 在组件在视图层布局完成后执行
- console.log(TAG_NAME, 'ready');
- },
- destroyed: function() {
- // 在组件实例被从页面节点树移除时执行
- console.log(TAG_NAME, 'detached'); // 停止所有拉流,并重置数据
- this.exitRoom();
- },
- error: function(error) {
- // 每当组件方法抛出错误时执行
- console.log(TAG_NAME, 'error', error);
- },
- onPageShow: function() {
- // 组件所在的页面被展示时执行
- console.log(TAG_NAME, 'show status:', this.status);
- if (this.status.isPending) {
- // 经历了 5000 挂起事件
- this.status.isPending = false;
- }
- if (this.status.isPush) {
- // 小程序hide - show 有一定概率本地黑屏或静止,远端正常,或者远端和本地同时黑屏或静止,需要手动启动预览,非必现
- // this.data.pusher.getPusherContext().startPreview()
- // this.data.pusher.getPusherContext().resume()
- }
- },
- onPageHide: function() {
- // 组件所在的页面被隐藏时执行
- console.log(TAG_NAME, 'hide');
- },
- onPageResize: function(size) {
- // 组件所在的页面尺寸变化时执行
- console.log(TAG_NAME, 'resize', size);
- },
- methods: {
- setData,
- /**
- * 初始化各项参数和用户控制模块,在组件实例触发 attached 时调用,此时不建议对View进行变更渲染(调用setData方法)
- */
- initFun: function() {
- console.log(TAG_NAME, '_init');
- this.userController = new UserController(this);
- this._emitter = new Event();
- this.EVENT = EVENT;
- this.initStatusFun();
- this.bindEventFun();
- this.bindEventGridFun();
- console.log(TAG_NAME, '_init success component:', this);
- },
- /**
- * 进房
- * @param {Object} params 必传 roomID 取值范围 1 ~ 4294967295
- * @returns {Promise}
- */
- enterRoom: function(params) {
- return new Promise((resolve, reject) => {
- console.log(TAG_NAME, 'enterRoom');
- console.log(TAG_NAME, 'params', params);
- console.log(TAG_NAME, 'config', this.config);
- console.log(TAG_NAME, 'pusher', this.pusher); // 1. 补齐进房参数,校验必要参数是否齐全
- console.log('进房......', params, this.config, this.pusher);
- if (this.config.enableIM && this.config.sdkAppID) {
- this._initIM(this.config,params.roomID)
- // this._loginIM({ ...this.config, roomID: params.roomID })
- }
- if (params) {
- Object.assign(this.pusher, params);
- Object.assign(this.config, params);
- }
- if (!this.checkParamFun(this.config)) {
- reject(new Error('缺少必要参数'));
- return;
- } // 2. 根据参数拼接 push url,赋值给 live-pusher,
- this.getPushUrlFun(this.config)
- .then(pushUrl => {
- this.pusher.url = pushUrl;
- this.setData(
- {
- pusher: this.pusher
- },
- () => {
- console.log(TAG_NAME, 'enterRoom success', this.pusher); // view 渲染成功回调后,开始推流
- this.pusher.getPusherContext().start();
- this.status.isPush = true;
- resolve();
- }
- );
- })
- .catch(res => {
- // 获取 room sig 失败, 进房失败需要通过 pusher state 事件通知
- console.error(TAG_NAME, 'enterRoom fail', res);
- reject(res);
- });
- });
- },
- /**
- * 退房,停止推流和拉流,并重置数据
- * @returns {Promise}
- */
- exitRoom: function() {
- return new Promise((resolve, reject) => {
- console.log(TAG_NAME, 'exitRoom');
- this.pusher.reset();
- this.status.isPush = false;
- const result = this.userController.reset();
- this._exitIM();
- this.setData(
- {
- pusher: this.pusher,
- userList: result.userList,
- streamList: result.streamList
- },
- () => {
- // 在销毁页面时调用,不会走到这里
- resolve({
- userList: this.userList,
- streamList: this.streamList
- });
- console.log(TAG_NAME, 'exitRoom success', this.pusher, this.streamList, this.userList);
- }
- );
- });
- },
- /**
- * 开启摄像头
- * @returns {Promise}
- */
- publishLocalVideo: function() {
- // 设置 pusher enableCamera
- console.log(TAG_NAME, 'publishLocalVideo 开启摄像头');
- return this.setPusherConfigFun({
- enableCamera: true
- });
- },
- /**
- * 关闭摄像头
- * @returns {Promise}
- */
- unpublishLocalVideo: function() {
- // 设置 pusher enableCamera
- console.log(TAG_NAME, 'unpublshLocalVideo 关闭摄像头');
- return this.setPusherConfigFun({
- enableCamera: false
- });
- },
- /**
- * 开启麦克风
- * @returns {Promise}
- */
- publishLocalAudio: function() {
- // 设置 pusher enableCamera
- console.log(TAG_NAME, 'publishLocalAudio 开启麦克风');
- return this.setPusherConfigFun({
- enableMic: true
- });
- },
- /**
- * 关闭麦克风
- * @returns {Promise}
- */
- unpublishLocalAudio: function() {
- // 设置 pusher enableCamera
- console.log(TAG_NAME, 'unpublshLocalAudio 关闭麦克风');
- return this.setPusherConfigFun({
- enableMic: false
- });
- },
- /**
- * 订阅远端视频 主流 小画面 辅流
- * @param {Object} params {userID,streamType} streamType 传入 small 时修改对应的主流url的 streamtype 参数为small
- * @returns {Promise}
- */
- subscribeRemoteVideo(params) {
- console.log(TAG_NAME, 'subscribeRemoteVideo', params); // 设置指定 user streamType 的 muteVideo 为 false
- const config = {
- muteVideo: false
- }; // 本地数据结构里的 streamType 只支持 main 和 aux ,订阅small 也是对main进行处理
- const streamType = params.streamType === 'small' ? 'main' : params.streamType;
- if (params.streamType === 'small' || params.streamType === 'main') {
- const stream = this.userController.getStream({
- userID: params.userID,
- streamType: streamType
- });
- if (stream && stream.streamType === 'main') {
- console.log(TAG_NAME, 'subscribeRemoteVideo switch small', stream.src);
- if (params.streamType === 'small') {
- config.src = stream.src.replace('main', 'small');
- config._definitionType = 'small'; // 用于设置面板的渲染
- } else if (params.streamType === 'main') {
- stream.src = stream.src.replace('small', 'main');
- config._definitionType = 'main';
- }
- console.log(TAG_NAME, 'subscribeRemoteVideo', stream.src);
- }
- }
- return this.setPlayerConfigFun({
- userID: params.userID,
- streamType: streamType,
- config: config
- });
- },
- /**
- * 取消订阅远端视频
- * @param {Object} params {userID,streamType}
- * @returns {Promise}
- */
- unsubscribeRemoteVideo(params) {
- console.log(TAG_NAME, 'unsubscribeRemoteVideo', params); // 设置指定 user streamType 的 muteVideo 为 true
- return this.setPlayerConfigFun({
- userID: params.userID,
- streamType: params.streamType,
- config: {
- muteVideo: true
- }
- });
- },
- /**
- * 订阅远端音频
- * @param {Object} params userID 用户ID
- * @returns {Promise}
- */
- subscribeRemoteAudio(params) {
- console.log(TAG_NAME, 'subscribeRemoteAudio', params);
- return this.setPlayerConfigFun({
- userID: params.userID,
- streamType: 'main',
- config: {
- muteAudio: false
- }
- });
- },
- /**
- * 取消订阅远端音频
- * @param {Object} params userID 用户ID
- * @returns {Promise}
- */
- unsubscribeRemoteAudio(params) {
- console.log(TAG_NAME, 'unsubscribeRemoteAudio', params);
- return this.setPlayerConfigFun({
- userID: params.userID,
- streamType: 'main',
- config: {
- muteAudio: true
- }
- });
- },
- on: function(eventCode, handler, context) {
- this._emitter.on(eventCode, handler, context);
- },
- off: function(eventCode, handler) {
- this._emitter.off(eventCode, handler);
- },
- getRemoteUserList: function() {
- return this.userList;
- },
- /**
- * 切换前后摄像头
- */
- switchCamera: function() {
- if (!this.cameraPosition) {
- // this.data.pusher.cameraPosition 是初始值,不支持动态设置
- this.cameraPosition = this.pusher.frontCamera;
- }
- console.log(TAG_NAME, 'switchCamera', this.cameraPosition);
- this.cameraPosition = this.cameraPosition === 'front' ? 'back' : 'front';
- this.setData(
- {
- cameraPosition: this.cameraPosition
- },
- () => {
- console.log(TAG_NAME, 'switchCamera success', this.cameraPosition);
- }
- ); // wx 7.0.9 不支持动态设置 pusher.devicePosition ,需要调用api设置,这里修改cameraPosition是为了记录状态
- this.pusher.getPusherContext().switchCamera();
- },
- /**
- * 设置指定player view的渲染坐标和尺寸
- * @param {object} params
- * userID: string
- * streamType: string
- * xAxis: number
- * yAxis: number
- * width: number
- * height: number
- * @returns {Promise}
- */
- setViewRect: function(params) {
- console.log(TAG_NAME, 'setViewRect', params);
- if (this.pusher.template !== 'custom') {
- console.warn(`如需使用setViewRect方法,请设置template:"custom", 当前 template:"${this.pusher.template}"`);
- }
- if (this.pusher.userID === params.userID) {
- return this.setPusherConfigFun({
- xAxis: params.xAxis,
- yAxis: params.yAxis,
- width: params.width,
- height: params.height
- });
- }
- return this.setPlayerConfigFun({
- userID: params.userID,
- streamType: params.streamType,
- config: {
- xAxis: params.xAxis,
- yAxis: params.yAxis,
- width: params.width,
- height: params.height
- }
- });
- },
- /**
- * 设置指定 player 或者 pusher view 是否可见
- * @param {object} params
- * userID: string
- * streamType: string
- * isVisible:boolean
- * @returns {Promise}
- */
- setViewVisible: function(params) {
- console.log(TAG_NAME, 'setViewVisible', params); // if (this.data.pusher.template !== 'custom') {
- // console.warn(`如需使用setViewVisible方法,请设置template:"custom", 当前 template:"${this.data.pusher.template}"`)
- // }
- if (this.pusher.userID === params.userID) {
- return this.setPusherConfigFun({
- isVisible: params.isVisible
- });
- }
- return this.setPlayerConfigFun({
- userID: params.userID,
- streamType: params.streamType,
- config: {
- isVisible: params.isVisible
- }
- });
- },
- /**
- * 设置指定player view的层级
- * @param {Object} params
- * userID: string
- * streamType: string
- * zindex: number
- * @returns {Promise}
- */
- setViewZIndex: function(params) {
- console.log(TAG_NAME, 'setViewZIndex', params);
- if (this.pusher.template !== 'custom') {
- console.warn(`如需使用setViewZIndex方法,请设置template:"custom", 当前 template:"${this.pusher.template}"`);
- }
- if (this.pusher.userID === params.userID) {
- return this.setPusherConfigFun({
- zindex: params.zindex
- });
- }
- return this.setPlayerConfigFun({
- userID: params.userID,
- streamType: params.streamType,
- config: {
- zindex: params.zindex
- }
- });
- },
- /**
- * 播放背景音
- * @param {Object} params url
- * @returns {Promise}
- */
- playBGM: function(params) {
- return new Promise((resolve, reject) => {
- this.pusher.getPusherContext().playBGM({
- url: params.url,
- // 已经有相关事件不需要在这里监听,目前用于测试
- success: () => {
- console.log(TAG_NAME, '播放背景音成功'); // this._emitter.emit(EVENT.BGM_PLAY_START)
- resolve();
- },
- fail: () => {
- console.log(TAG_NAME, '播放背景音失败');
- this._emitter.emit(EVENT.BGM_PLAY_FAIL);
- reject(new Error('播放背景音失败'));
- } // complete: () => {
- // console.log(TAG_NAME, '背景完成')
- // this._emitter.emit(EVENT.BGM_PLAY_COMPLETE)
- // },
- });
- });
- },
- stopBGM: function() {
- this.pusher.getPusherContext().stopBGM();
- },
- pauseBGM: function() {
- this.pusher.getPusherContext().pauseBGM();
- },
- resumeBGM: function() {
- this.pusher.getPusherContext().resumeBGM();
- },
- /**
- * 设置背景音音量
- * @param {Object} params volume
- */
- setBGMVolume: function(params) {
- this.pusher.getPusherContext().setBGMVolume({
- volume: params.volume
- });
- },
- /**
- * 设置麦克风音量
- * @param {Object} params volume
- */
- setMICVolume: function(params) {
- this.pusher.getPusherContext().setMICVolume({
- volume: params.volume
- });
- },
- /**
- * 发送SEI消息
- * @param {Object} params message
- * @returns {Promise}
- */
- sendSEI: function(params) {
- return new Promise((resolve, reject) => {
- this.pusher.getPusherContext().sendMessage({
- msg: params.message,
- success: function(result) {
- resolve(result);
- }
- });
- });
- },
- /**
- * pusher 和 player 的截图并保存
- * @param {Object} params userID streamType
- * @returns {Promise}
- */
- snapshot: function(params) {
- console.log(TAG_NAME, 'snapshot', params);
- return new Promise((resolve, reject) => {
- this.captureSnapshot(params)
- .then(result => {
- wx.saveImageToPhotosAlbum({
- filePath: result.tempImagePath,
- success(res) {
- wx.showToast({
- title: '已保存到相册'
- });
- console.log('save photo is success', res);
- resolve(result);
- },
- fail: function(error) {
- wx.showToast({
- icon: 'none',
- title: '保存失败'
- });
- console.log('save photo is fail', error);
- reject(error);
- }
- });
- })
- .catch(error => {
- reject(error);
- });
- });
- },
- /**
- * 获取pusher 和 player 的截图
- * @param {Object} params userID streamType
- * @returns {Promise}
- */
- captureSnapshot: function(params) {
- return new Promise((resolve, reject) => {
- if (params.userID === this.pusher.userID) {
- // pusher
- this.pusher.getPusherContext().snapshot({
- quality: 'raw',
- complete: result => {
- console.log(TAG_NAME, 'snapshot pusher', result);
- if (result.tempImagePath) {
- resolve(result);
- } else {
- console.log('snapShot 回调失败', result);
- reject(new Error('截图失败'));
- }
- }
- });
- } else {
- // player
- this.userController.getStream(params).playerContext.snapshot({
- quality: 'raw',
- complete: result => {
- console.log(TAG_NAME, 'snapshot player', result);
- if (result.tempImagePath) {
- resolve(result);
- } else {
- console.log('snapShot 回调失败', result);
- reject(new Error('截图失败'));
- }
- }
- });
- }
- });
- },
- /**
- * 将远端视频全屏
- * @param {Object} params userID streamType direction
- * @returns {Promise}
- */
- enterFullscreen: function(params) {
- console.log(TAG_NAME, 'enterFullscreen', params);
- return new Promise((resolve, reject) => {
- this.userController.getStream(params).playerContext.requestFullScreen({
- direction: params.direction || 0,
- success: event => {
- console.log(TAG_NAME, 'enterFullscreen success', event);
- resolve(event);
- },
- fail: event => {
- console.log(TAG_NAME, 'enterFullscreen fail', event);
- reject(event);
- }
- });
- });
- },
- /**
- * 将远端视频取消全屏
- * @param {Object} params userID streamType
- * @returns {Promise}
- */
- exitFullscreen: function(params) {
- console.log(TAG_NAME, 'exitFullscreen', params);
- return new Promise((resolve, reject) => {
- this.userController.getStream(params).playerContext.exitFullScreen({
- success: event => {
- console.log(TAG_NAME, 'exitFullScreen success', event);
- resolve(event);
- },
- fail: event => {
- console.log(TAG_NAME, 'exitFullScreen fail', event);
- reject(event);
- }
- });
- });
- },
- /**
- * 设置 player 视图的横竖屏显示
- * @param {Object} params userID streamType orientation: vertical, horizontal
- * @returns {Promise}
- */
- setRemoteOrientation: function(params) {
- return this.setPlayerConfigFun({
- userID: params.userID,
- streamType: params.streamType,
- config: {
- orientation: params.orientation
- }
- });
- },
- // 改为:
- setViewOrientation: function(params) {
- return this.setPlayerConfigFun({
- userID: params.userID,
- streamType: params.streamType,
- config: {
- orientation: params.orientation
- }
- });
- },
- /**
- * 设置 player 视图的填充模式
- * @param {Object} params userID streamType fillMode: contain,fillCrop
- * @returns {Promise}
- */
- setRemoteFillMode: function(params) {
- return this.setPlayerConfigFun({
- userID: params.userID,
- streamType: params.streamType,
- config: {
- objectFit: params.fillMode
- }
- });
- },
- // 改为:
- setViewFillMode: function(params) {
- return this.setPlayerConfigFun({
- userID: params.userID,
- streamType: params.streamType,
- config: {
- objectFit: params.fillMode
- }
- });
- },
- /**
- * 切换 player 大小画面
- * @param {Object} params userID streamType definition: HD SD
- * @returns {Promise}
- */
- setRemoteDefinitionFun: function(params) {
- params.streamType = 'main';
- return new Promise((resolve, reject) => {
- const stream = this.userController.getStream({
- userID: params.userID,
- streamType: params.streamType
- });
- if (stream && stream.streamType === 'main') {
- console.log(TAG_NAME, '_switchStreamType', stream.src); // stream.volume = volume
- if (stream.src.indexOf('main') > -1) {
- stream.src = stream.src.replace('main', 'small');
- stream._streamType = 'small'; // 用于设置面板的渲染
- } else if (stream.src.indexOf('small') > -1) {
- stream.src = stream.src.replace('small', 'main');
- stream._streamType = 'main';
- }
- console.log(TAG_NAME, '_switchStreamType', stream.src);
- this.setData(
- {
- streamList: this.streamList
- },
- () => {}
- );
- }
- });
- },
- initStatusFun() {
- this.status = {
- isPush: false,
- // 推流状态
- isPending: false // 挂起状态,触发5000事件标记为true,onShow后标记为false
- };
- this._lastTapTime = 0;
- this._beforeLastTapTime = 0;
- this._isFullscreen = false;
- },
- /**
- * 设置推流参数并触发页面渲染更新
- * @param {Object} config live-pusher 的配置
- * @returns {Promise}
- */
- setPusherConfigFun(config) {
- console.log(TAG_NAME, '_setPusherConfig', config, this.pusher);
- return new Promise((resolve, reject) => {
- if (!this.pusher) {
- this.pusher = new Pusher(config);
- } else {
- Object.assign(this.pusher, config);
- }
- this.setData(
- {
- pusher: this.pusher
- },
- () => {
- // console.log(TAG_NAME, '_setPusherConfig setData compelete', 'config:', config, 'pusher:', this.data.pusher)
- resolve(config);
- }
- );
- });
- },
- /**
- *
- * @param {Object} params include userID,streamType,config
- * @returns {Promise}
- */
- setPlayerConfigFun(params) {
- const userID = params.userID;
- const streamType = params.streamType;
- const config = params.config;
- console.log(TAG_NAME, '_setPlayerConfig', params);
- return new Promise((resolve, reject) => {
- // 获取指定的userID streamType 的 stream
- const user = this.userController.getUser(userID);
- if (user && user.streams[streamType]) {
- user.streams[streamType] = Object.assign(user.streams[streamType], config); // user.streams引用的对象和 streamList 里的是同一个
- this.setData(
- {
- streamList: this.streamList
- },
- () => {
- // console.log(TAG_NAME, '_setPlayerConfig complete', params, 'streamList:', this.data.streamList)
- resolve(params);
- }
- );
- } else {
- // 不需要reject,静默处理
- console.warn(TAG_NAME, '指定 userID 或者 streamType 不存在'); // reject(new Error('指定 userID 或者 streamType 不存在'))
- }
- });
- },
- /**
- * 必选参数检测
- * @param {Object} rtcConfig rtc参数
- * @returns {Boolean}
- */
- checkParamFun: function(rtcConfig) {
- console.log(TAG_NAME, 'checkParam config:', rtcConfig);
- if (!rtcConfig.sdkAppID) {
- console.error('未设置 sdkAppID');
- return false;
- }
- if (rtcConfig.roomID === undefined) {
- console.error('未设置 roomID');
- return false;
- }
- if (rtcConfig.roomID < 1 || rtcConfig.roomID > 4294967296) {
- console.error('roomID 超出取值范围 1 ~ 4294967295');
- return false;
- }
- if (!rtcConfig.userID) {
- console.error('未设置 userID');
- return false;
- }
- if (!rtcConfig.userSig) {
- console.error('未设置 userSig');
- return false;
- }
- if (!rtcConfig.template) {
- console.error('未设置 template');
- return false;
- }
- return true;
- },
- getPushUrlFun: function(rtcConfig) {
- // 拼接 puhser url rtmp 方案
- console.log(TAG_NAME, 'getPushUrl', rtcConfig);
- if (ENV.IS_TRTC) {
- // 版本高于7.0.8,基础库版本高于2.10.0 使用新的 url
- return new Promise((resolve, reject) => {
- // appscene videocall live
- // cloudenv PRO CCC DEV UAT
- // encsmall 0
- // 对外的默认值是rtc ,对内的默认值是videocall
- rtcConfig.scene = !rtcConfig.scene || rtcConfig.scene === 'rtc' ? 'videocall' : 'live';
- rtcConfig.enableBlackStream = rtcConfig.enableBlackStream || 1;
- rtcConfig.encsmall = rtcConfig.encsmall || 0;
- rtcConfig.cloudenv = rtcConfig.cloudenv || 'PRO';
- setTimeout(() => {
- const pushUrl =
- 'room://cloud.tencent.com/rtc?sdkappid=' +
- rtcConfig.sdkAppID +
- '&roomid=' +
- rtcConfig.roomID +
- '&userid=' +
- rtcConfig.userID +
- '&usersig=' +
- rtcConfig.userSig +
- '&appscene=' +
- rtcConfig.scene +
- '&encsmall=' +
- rtcConfig.encsmall +
- '&cloudenv=' +
- rtcConfig.cloudenv;
- console.log(TAG_NAME, 'getPushUrl result:', pushUrl);
- resolve(pushUrl);
- }, 0);
- });
- }
- return this.requestSigServerFun(rtcConfig);
- },
- /**
- * 获取签名和推流地址
- * @param {Object} rtcConfig 进房参数配置
- * @returns {Promise}
- */
- requestSigServerFun: function(rtcConfig) {
- console.log('requestSigServer:', rtcConfig);
- const sdkAppID = rtcConfig.sdkAppID;
- const userID = rtcConfig.userID;
- const userSig = rtcConfig.userSig;
- const roomID = rtcConfig.roomID;
- const privateMapKey = rtcConfig.privateMapKey;
- rtcConfig.useCloud = rtcConfig.useCloud === undefined ? true : rtcConfig.useCloud;
- let url = rtcConfig.useCloud ? 'https://official.opensso.tencent-cloud.com/v4/openim/jsonvideoapp' : 'https://yun.tim.qq.com/v4/openim/jsonvideoapp';
- url += '?sdkappid=' + sdkAppID + '&identifier=' + userID + '&usersig=' + userSig + '&random=' + Date.now() + '&contenttype=json';
- const reqHead = {
- Cmd: 1,
- SeqNo: 1,
- BusType: 7,
- GroupId: roomID
- };
- const reqBody = {
- PrivMapEncrypt: privateMapKey,
- TerminalType: 1,
- FromType: 3,
- SdkVersion: 26280566
- };
- console.log('requestSigServer:', url, reqHead, reqBody);
- return new Promise((resolve, reject) => {
- wx.request({
- url: url,
- data: {
- ReqHead: reqHead,
- ReqBody: reqBody
- },
- method: 'POST',
- success: res => {
- console.log('requestSigServer success:', res);
- if (res.data['ErrorCode'] || res.data['RspHead']['ErrorCode'] !== 0) {
- // console.error(res.data['ErrorInfo'] || res.data['RspHead']['ErrorInfo'])
- console.error('获取roomsig失败');
- reject(res);
- }
- const roomSig = JSON.stringify(res.data['RspBody']);
- let pushUrl = 'room://cloud.tencent.com?sdkappid=' + sdkAppID + '&roomid=' + roomID + '&userid=' + userID + '&roomsig=' + encodeURIComponent(roomSig); // TODO 需要重新整理的逻辑
- // 如果有配置纯音频推流或者recordId参数
- if (rtcConfig.pureAudioPushMod || rtcConfig.recordId) {
- const bizbuf = {
- Str_uc_params: {
- pure_audio_push_mod: 0,
- record_id: 0
- }
- }; // 纯音频推流
- if (rtcConfig.pureAudioPushMod) {
- bizbuf.Str_uc_params.pure_audio_push_mod = rtcConfig.pureAudioPushMod;
- } else {
- delete bizbuf.Str_uc_params.pure_audio_push_mod;
- } // 自动录制时业务自定义id
- if (rtcConfig.recordId) {
- bizbuf.Str_uc_params.record_id = rtcConfig.recordId;
- } else {
- delete bizbuf.Str_uc_params.record_id;
- }
- pushUrl += '&bizbuf=' + encodeURIComponent(JSON.stringify(bizbuf));
- }
- console.log('roomSigInfo', pushUrl);
- resolve(pushUrl);
- },
- fail: res => {
- console.log('requestSigServer fail:', res);
- reject(res);
- }
- });
- });
- },
- doubleTabToggleFullscreenFun: function(event) {
- const curTime = event.timeStamp;
- const lastTime = this._lastTapTime; // 已知问题:上次全屏操作后,必须等待1.5s后才能再次进行全屏操作,否则引发SDK全屏异常,因此增加节流逻辑
- const beforeLastTime = this._beforeLastTapTime;
- console.log(TAG_NAME, 'doubleTabToggleFullscreenFun', event, lastTime, beforeLastTime);
- if (curTime - lastTime > 0 && curTime - lastTime < 300 && lastTime - beforeLastTime > 1500) {
- const userID = event.currentTarget.dataset.userid;
- const streamType = event.currentTarget.dataset.streamtype;
- if (this._isFullscreen) {
- this.exitFullscreen({
- userID,
- streamType
- })
- .then(() => {
- this._isFullscreen = false;
- })
- .catch(() => {});
- } else {
- // const stream = this.userController.getStream({ userID, streamType })
- let direction; // // 已知问题:视频的尺寸需要等待player触发NetStatus事件才能获取到,如果进房就双击全屏,全屏后的方向有可能不对。
- // if (stream && stream.videoWidth && stream.videoHeight) {
- // // 如果是横视频,全屏时进行横屏处理。如果是竖视频,则为0
- // direction = stream.videoWidth > stream.videoHeight ? 90 : 0
- // }
- this.enterFullscreen({
- userID,
- streamType,
- direction
- })
- .then(() => {
- this._isFullscreen = true;
- })
- .catch(() => {});
- }
- this._beforeLastTapTime = lastTime;
- }
- this._lastTapTime = curTime;
- },
- /**
- * TRTC-room 远端用户和音视频状态处理
- */
- bindEventFun: function() {
- // 远端用户进房
- this.userController.on(EVENT.REMOTE_USER_JOIN, event => {
- console.log(TAG_NAME, '远端用户进房', event, event.data.userID);
- this.setData(
- {
- userList: event.data.userList
- },
- () => {
- this._emitter.emit(EVENT.REMOTE_USER_JOIN, {
- userID: event.data.userID
- });
- }
- );
- console.log(TAG_NAME, 'REMOTE_USER_JOIN', 'streamList:', this.streamList, 'userList:', this.userList);
- }); // 远端用户离开
- this.userController.on(EVENT.REMOTE_USER_LEAVE, event => {
- console.log(TAG_NAME, '远端用户离开', event, event.data.userID);
- if (event.data.userID) {
- this.setData(
- {
- userList: event.data.userList,
- streamList: event.data.streamList
- },
- () => {
- this._emitter.emit(EVENT.REMOTE_USER_LEAVE, {
- userID: event.data.userID
- });
- }
- );
- }
- console.log(TAG_NAME, 'REMOTE_USER_LEAVE', 'streamList:', this.streamList, 'userList:', this.userList);
- }); // 视频状态 true
- this.userController.on(EVENT.REMOTE_VIDEO_ADD, event => {
- console.log(TAG_NAME, '远端视频可用', event, event.data.stream.userID);
- const stream = event.data.stream;
- this.setData(
- {
- userList: event.data.userList,
- streamList: event.data.streamList
- },
- () => {
- // 完善 的stream 的 playerContext
- stream.playerContext = wx.createLivePlayerContext(stream.streamID, this); // 新增的需要触发一次play 默认属性才能生效
- // stream.playerContext.play()
- // console.log(TAG_NAME, 'REMOTE_VIDEO_ADD playerContext.play()', stream)
- // TODO 视频通话模版默认订阅且显示
- this._emitter.emit(EVENT.REMOTE_VIDEO_ADD, {
- userID: stream.userID,
- streamType: stream.streamType
- });
- }
- );
- console.log(TAG_NAME, 'REMOTE_VIDEO_ADD', 'streamList:', this.streamList, 'userList:', this.userList);
- }); // 视频状态 false
- this.userController.on(EVENT.REMOTE_VIDEO_REMOVE, event => {
- console.log(TAG_NAME, '远端视频移除', event, event.data.stream.userID);
- const stream = event.data.stream;
- this.setData(
- {
- userList: event.data.userList,
- streamList: event.data.streamList
- },
- () => {
- // 有可能先触发了退房事件,用户名下的所有stream都已清除
- if (stream.userID && stream.streamType) {
- this._emitter.emit(EVENT.REMOTE_VIDEO_REMOVE, {
- userID: stream.userID,
- streamType: stream.streamType
- });
- }
- }
- );
- console.log(TAG_NAME, 'REMOTE_VIDEO_REMOVE', 'streamList:', this.streamList, 'userList:', this.userList);
- }); // 音频可用
- this.userController.on(EVENT.REMOTE_AUDIO_ADD, event => {
- console.log(TAG_NAME, '远端音频可用', event);
- const stream = event.data.stream;
- this.setData(
- {
- userList: event.data.userList,
- streamList: event.data.streamList
- },
- () => {
- stream.playerContext = wx.createLivePlayerContext(stream.streamID, this); // 新增的需要触发一次play 默认属性才能生效
- // stream.playerContext.play()
- // console.log(TAG_NAME, 'REMOTE_AUDIO_ADD playerContext.play()', stream)
- this._emitter.emit(EVENT.REMOTE_AUDIO_ADD, {
- userID: stream.userID,
- streamType: stream.streamType
- });
- }
- );
- console.log(TAG_NAME, 'REMOTE_AUDIO_ADD', 'streamList:', this.streamList, 'userList:', this.userList);
- }); // 音频不可用
- this.userController.on(EVENT.REMOTE_AUDIO_REMOVE, event => {
- console.log(TAG_NAME, '远端音频移除', event, event.data.stream.userID);
- const stream = event.data.stream;
- this.setData(
- {
- userList: event.data.userList,
- streamList: event.data.streamList
- },
- () => {
- // 有可能先触发了退房事件,用户名下的所有stream都已清除
- if (stream.userID && stream.streamType) {
- this._emitter.emit(EVENT.REMOTE_AUDIO_REMOVE, {
- userID: stream.userID,
- streamType: stream.streamType
- });
- }
- }
- );
- console.log(TAG_NAME, 'REMOTE_AUDIO_REMOVE', 'streamList:', this.streamList, 'userList:', this.userList);
- });
- },
- /**
- * pusher event handler
- * @param {*} event 事件实例
- */
- pusherStateChangeHandlerFun: function(event) {
- const code = event.detail.code;
- const message = event.detail.message;
- console.log(TAG_NAME, 'pusherStateChange:', code, event);
- switch (code) {
- case 0:
- console.log(message, code);
- break;
- case 1001:
- console.log('已经连接推流服务器', code);
- break;
- case 1002:
- console.log('已经与服务器握手完毕,开始推流', code);
- break;
- case 1003:
- console.log('打开摄像头成功', code);
- break;
- case 1004:
- console.log('录屏启动成功', code);
- break;
- case 1005:
- console.log('推流动态调整分辨率', code);
- break;
- case 1006:
- console.log('推流动态调整码率', code);
- break;
- case 1007:
- console.log('首帧画面采集完成', code);
- break;
- case 1008:
- console.log('编码器启动', code);
- break;
- case 1018:
- console.log('进房成功', code);
- this._emitter.emit(EVENT.LOCAL_JOIN, {
- userID: this.pusher.userID
- });
- break;
- case 1019:
- console.log('退出房间', code);
- this._emitter.emit(EVENT.LOCAL_LEAVE, {
- userID: this.pusher.userID
- });
- break;
- case 2003:
- console.log('渲染首帧视频', code);
- break;
- case 1020:
- case 1031:
- case 1032:
- case 1033:
- case 1034:
- // 通过 userController 处理 1020 1031 1032 1033 1034
- this.userController.userEventHandler(event);
- break;
- case -1301:
- console.error('打开摄像头失败: ', code);
- this._emitter.emit(EVENT.ERROR, {
- code,
- message
- });
- break;
- case -1302:
- console.error('打开麦克风失败: ', code);
- this._emitter.emit(EVENT.ERROR, {
- code,
- message
- });
- break;
- case -1303:
- console.error('视频编码失败: ', code);
- this._emitter.emit(EVENT.ERROR, {
- code,
- message
- });
- break;
- case -1304:
- console.error('音频编码失败: ', code);
- this._emitter.emit(EVENT.ERROR, {
- code,
- message
- });
- break;
- case -1307:
- console.error('推流连接断开: ', code);
- this._emitter.emit(EVENT.ERROR, {
- code,
- message
- });
- break;
- case -100018:
- console.error('进房失败: ', code, message);
- this._emitter.emit(EVENT.ERROR, {
- code,
- message
- });
- break;
- case 5000:
- console.log('小程序被挂起: ', code); // 终端 sdk 建议执行退房操作,唤起时重新进房,临时解决方案,待小程序SDK完全实现自动重新推流后可以去掉
- this.status.isPending = true;
- if (this.status.isPush) {
- // this.exitRoom()
- const tempUrl = this.pusher.url;
- this.pusher.url = ''; // console.log('5000 小程序被挂起后更换pusher', this.data.pusher.getPusherContext().webviewId)
- this.setData(
- {
- pusher: this.pusher
- },
- () => {
- this.pusher.url = tempUrl;
- this.setData(
- {
- pusher: this.pusher
- },
- () => {
- this.pusher.getPusherContext().start();
- console.log('5000 小程序被挂起后更换pusher', this.pusher);
- }
- );
- }
- );
- }
- break;
- case 1021:
- console.log('网络类型发生变化,需要重新进房', code);
- break;
- case 2007:
- console.log('本地视频播放loading: ', code);
- break;
- case 2004:
- console.log('本地视频播放开始: ', code);
- break;
- default:
- console.log(message, code);
- }
- this._emitter.emit(EVENT.LOCAL_STATE_UPDATE, {
- data: event
- });
- },
- pusherNetStatusHandlerFun: function(event) {
- // 触发 LOCAL_NET_STATE_UPDATE
- this._emitter.emit(EVENT.LOCAL_NET_STATE_UPDATE, event);
- },
- pusherErrorHandlerFun: function(event) {
- // 触发 ERROR
- console.warn(TAG_NAME, 'pusher error', event);
- try {
- const code = event.detail.errCode;
- const message = event.detail.errMsg;
- this._emitter.emit(EVENT.ERROR, {
- code,
- message
- });
- } catch (exception) {
- console.error(TAG_NAME, 'pusher error data parser exception', event, exception);
- }
- },
- pusherBGMStartHandlerFun: function(event) {
- // 触发 BGM_START 已经在playBGM方法中进行处理
- // this._emitter.emit(EVENT.BGM_PLAY_START, { data: event })
- },
- pusherBGMProgressHandlerFun: function(event) {
- // BGM_PROGRESS
- this._emitter.emit(EVENT.BGM_PLAY_PROGRESS, event);
- },
- pusherBGMCompleteHandlerFun: function(event) {
- // BGM_COMPLETE
- this._emitter.emit(EVENT.BGM_PLAY_COMPLETE, event);
- },
- // player event handler
- // 获取 player ID 再进行触发
- playerStateChangeFun: function(event) {
- // console.log(TAG_NAME, 'playerStateChangeFun', event)
- this._emitter.emit(EVENT.REMOTE_STATE_UPDATE, event);
- },
- playerFullscreenChangeFun: function(event) {
- // console.log(TAG_NAME, '_playerFullscreenChange', event)
- this._emitter.emit(EVENT.REMOTE_NET_STATE_UPDATE, event);
- },
- playerNetStatusFun: function(event) {
- // console.log(TAG_NAME, 'playerNetStatusFun', event)
- // 获取player 视频的宽高
- const stream = this.userController.getStream({
- userID: event.currentTarget.dataset.userid,
- streamType: event.currentTarget.dataset.streamtype
- });
- if (stream && (stream.videoWidth !== event.detail.info.videoWidth || stream.videoHeight !== event.detail.info.videoHeight)) {
- console.log(TAG_NAME, 'playerNetStatusFun update video size', event);
- stream.videoWidth = event.detail.info.videoWidth;
- stream.videoHeight = event.detail.info.videoHeight;
- }
- this._emitter.emit(EVENT.REMOTE_FULLSCREEN_UPDATE, event);
- },
- playerAudioVolumeNotifyFun: function(event) {
- // console.log(TAG_NAME, 'playerAudioVolumeNotifyFun', event)
- this._emitter.emit(EVENT.REMOTE_AUDIO_VOLUME_UPDATE, event);
- },
- /**
- * 监听组件属性变更,外部变更组件属性时触发该监听,用于检查属性设置是否正常
- * @param {Object} data 变更数据
- */
- propertyObserverFun: function(data) {
- console.log(TAG_NAME, '_propertyObserver', data, this.config);
- if (data.name === 'config') {
- // const config = Object.assign(DEFAULT_PUSHER_CONFIG, data.newVal)
- const config = data.newVal; // querystring 只支持String类型,做一个类型防御
- if (typeof config.debugMode === 'string') {
- config.debugMode === 'true' ? true : false;
- } // 独立设置与pusher无关的配置
- this.setData({
- template: config.template,
- debugMode: config.debugMode || false,
- debug: config.debugMode || false
- });
- this.setPusherConfigFun(config);
- }
- },
- toggleVideoFun() {
- if (this.pusher.enableCamera) {
- this.unpublishLocalVideo();
- } else {
- this.publishLocalVideo();
- }
- },
- toggleAudioFun() {
- if (this.pusher.enableMic) {
- this.unpublishLocalAudio();
- } else {
- this.publishLocalAudio();
- }
- },
- debugToggleRemoteVideoFun(event) {
- console.log(TAG_NAME, '_debugToggleRemoteVideo', event.currentTarget.dataset);
- const userID = event.currentTarget.dataset.userID;
- const streamType = event.currentTarget.dataset.streamType;
- const stream = this.streamList.find(item => {
- return item.userID === userID && item.streamType === streamType;
- });
- if (stream.muteVideo) {
- this.subscribeRemoteVideo({
- userID,
- streamType
- });
- this.setViewVisible({
- userID,
- streamType,
- isVisible: true
- });
- } else {
- this.unsubscribeRemoteVideo({
- userID,
- streamType
- });
- this.setViewVisible({
- userID,
- streamType,
- isVisible: false
- });
- }
- },
- debugToggleRemoteAudioFun(event) {
- console.log(TAG_NAME, '_debugToggleRemoteAudio', event.currentTarget.dataset);
- const userID = event.currentTarget.dataset.userID;
- const streamType = event.currentTarget.dataset.streamType;
- const stream = this.streamList.find(item => {
- return item.userID === userID && item.streamType === streamType;
- });
- if (stream.muteAudio) {
- this.subscribeRemoteAudio({
- userID
- });
- } else {
- this.unsubscribeRemoteAudio({
- userID
- });
- }
- },
- debugToggleVideoDebugFun() {
- this.setData({
- debug: !this.debug
- });
- },
- debugExitRoomFun() {
- this.exitRoom();
- },
- debugEnterRoomFun() {
- this.publishLocalVideo();
- this.publishLocalAudio();
- this.enterRoom({
- roomID: this.config.roomID
- }).then(() => {
- // 进房后开始推送视频或音频
- });
- },
- debugGoBackFun() {
- wx.navigateBack({
- delta: 1
- });
- },
- debugTogglePanelFun() {
- this.setData({
- debugPanel: !this.debugPanel
- });
- },
- toggleAudioVolumeTypeFun() {
- if (this.pusher.audioVolumeType === 'voicecall') {
- this.setPusherConfigFun({
- audioVolumeType: 'media'
- });
- } else {
- this.setPusherConfigFun({
- audioVolumeType: 'voicecall'
- });
- }
- },
- toggleSoundModeFun() {
- if (this.userList.length === 0) {
- return;
- }
- const stream = this.userController.getStream({
- userID: this.userList[0].userID,
- streamType: 'main'
- });
- if (stream) {
- if (stream.soundMode === 'speaker') {
- stream['soundMode'] = 'ear';
- } else {
- stream['soundMode'] = 'speaker';
- }
- this.setPlayerConfigFun({
- userID: stream.userID,
- streamType: 'main',
- config: {
- soundMode: stream['soundMode']
- }
- });
- }
- },
- /**
- * 退出通话
- */
- hangUpFun: function() {
- this.exitRoom();
- wx.navigateBack({
- delta: 1
- });
- },
- /**
- * 切换订阅音频状态
- */
- handleSubscribeAudio: function() {
- if (this.pusher.enableMic) {
- this.unpublishLocalAudio();
- } else {
- this.publishLocalAudio();
- }
- },
- /**
- * 切换订阅远端视频状态
- * @param event
- */
- handleSubscribeRemoteVideoFun: function(event) {
- const userID = event.currentTarget.dataset.userID;
- const streamType = event.currentTarget.dataset.streamType;
- const stream = this.streamList.find(item => {
- return item.userID === userID && item.streamType === streamType;
- });
- if (stream.muteVideo) {
- this.subscribeRemoteVideo({
- userID,
- streamType
- });
- } else {
- this.unsubscribeRemoteVideo({
- userID,
- streamType
- });
- }
- },
- /**
- * 将远端视频取消全屏
- * @param event
- */
- handleSubscribeRemoteAudioFun: function(event) {
- const userID = event.currentTarget.dataset.userID;
- const streamType = event.currentTarget.dataset.streamType;
- const stream = this.streamList.find(item => {
- return item.userID === userID && item.streamType === streamType;
- });
- if (stream.muteAudio) {
- this.subscribeRemoteAudio({
- userID
- });
- } else {
- this.unsubscribeRemoteAudio({
- userID
- });
- }
- },
- /**
- * grid布局, 唤起 memberlist-panel
- */
- switchMemberListPanelFun() {
- this.setData({
- panelName: this.panelName !== 'memberlist-panel' ? 'memberlist-panel' : ''
- });
- },
- /**
- * grid布局, 唤起setting-panel
- */
- switchSettingPanelFun() {
- this.setData({
- panelName: this.panelName !== 'setting-panel' ? 'setting-panel' : ''
- });
- },
- handleMaskerClickFun() {
- this.setData({
- panelName: ''
- });
- },
- setPuserPropertyFun(event) {
- // console.log(TAG_NAME, '_setPuserProperty', event)
- const key = event.currentTarget.dataset.key;
- let value = event.currentTarget.dataset.value;
- const config = {};
- if (value === 'true') {
- value = true;
- } else if (value === 'false') {
- value = false;
- }
- if (typeof value === 'boolean') {
- config[key] = !this.pusher[key];
- } else if (typeof value === 'string' && value.indexOf('|') > 0) {
- value = value.split('|');
- if (this.pusher[key] === value[0]) {
- config[key] = value[1];
- } else {
- config[key] = value[0];
- }
- } // console.log(TAG_NAME, '_setPuserProperty', config)
- this.setPusherConfigFun(config);
- },
- setPlayerPropertyFun(event) {
- console.log(TAG_NAME, '_setPlayerProperty', event);
- const userID = event.currentTarget.dataset.userid;
- const streamType = event.currentTarget.dataset.streamtype;
- const key = event.currentTarget.dataset.key;
- let value = event.currentTarget.dataset.value;
- const stream = this.userController.getStream({
- userID: userID,
- streamType: streamType
- });
- if (!stream) {
- return;
- }
- const config = {};
- if (value === 'true') {
- value = true;
- } else if (value === 'false') {
- value = false;
- }
- if (typeof value === 'boolean') {
- config[key] = !stream[key];
- } else if (typeof value === 'string' && value.indexOf('|') > 0) {
- value = value.split('|');
- if (stream[key] === value[0]) {
- config[key] = value[1];
- } else {
- config[key] = value[0];
- }
- }
- console.log(TAG_NAME, '_setPlayerProperty', config);
- this.setPlayerConfigFun({
- userID,
- streamType,
- config
- });
- },
- switchStreamTypeFun(event) {
- const userID = event.currentTarget.dataset.userid;
- const streamType = event.currentTarget.dataset.streamtype;
- const stream = this.userController.getStream({
- userID: userID,
- streamType: streamType
- });
- if (stream && stream.streamType === 'main') {
- if (stream._definitionType === 'small') {
- this.subscribeRemoteVideo({
- userID,
- streamType: 'main'
- });
- } else {
- this.subscribeRemoteVideo({
- userID,
- streamType: 'small'
- });
- }
- }
- },
- handleSnapshotClickFun(event) {
- wx.showToast({
- title: '开始截屏',
- icon: 'none',
- duration: 1000
- });
- const userID = event.currentTarget.dataset.userid;
- const streamType = event.currentTarget.dataset.streamtype;
- this.snapshot({
- userID,
- streamType
- });
- },
- /**
- * grid布局, 绑定事件
- */
- bindEventGridFun() {
- // 远端音量变更
- this.on(EVENT.REMOTE_AUDIO_VOLUME_UPDATE, event => {
- const data = event.data;
- const userID = data.currentTarget.dataset.userid;
- const streamType = data.currentTarget.dataset.streamtype;
- const volume = data.detail.volume; // console.log(TAG_NAME, '远端音量变更', userID, streamType, volume)
- const stream = this.userController.getStream({
- userID: userID,
- streamType: streamType
- });
- if (stream) {
- stream.volume = volume;
- }
- this.setData(
- {
- streamList: this.streamList
- },
- () => {}
- );
- });
- },
- toggleFullscreenFun(event) {
- console.log(TAG_NAME, '_toggleFullscreen', event);
- const userID = event.currentTarget.dataset.userID;
- const streamType = event.currentTarget.dataset.streamType;
- if (this._isFullscreen) {
- this.exitFullscreen({
- userID,
- streamType
- })
- .then(() => {
- this._isFullscreen = false;
- })
- .catch(() => {});
- } else {
- // const stream = this.userController.getStream({ userID, streamType })
- const direction = 0; // 已知问题:视频的尺寸需要等待player触发NetStatus事件才能获取到,如果进房就双击全屏,全屏后的方向有可能不对。
- // if (stream && stream.videoWidth && stream.videoHeight) {
- // // 如果是横视频,全屏时进行横屏处理。如果是竖视频,则为0
- // direction = stream.videoWidth > stream.videoHeight ? 90 : 0
- // }
- this.enterFullscreen({
- userID,
- streamType,
- direction
- })
- .then(() => {
- this._isFullscreen = true;
- })
- .catch(() => {});
- }
- },
- // ______ __ __ ______ __ __
- // | \| \ / \ | \ | \ | \
- // \$$$$$$| $$\ / $$ \$$$$$$ _______ _| $$_ ______ ______ _______ ______ | $$
- // | $$ | $$$\ / $$$ | $$ | \| $$ \ / \ / \ | \ | \ | $$
- // | $$ | $$$$\ $$$$ | $$ | $$$$$$$\\$$$$$$ | $$$$$$\| $$$$$$\| $$$$$$$\ \$$$$$$\| $$
- // | $$ | $$\$$ $$ $$ | $$ | $$ | $$ | $$ __ | $$ $$| $$ \$$| $$ | $$ / $$| $$
- // _| $$_ | $$ \$$$| $$ _| $$_ | $$ | $$ | $$| \| $$$$$$$$| $$ | $$ | $$| $$$$$$$| $$
- // | $$ \| $$ \$ | $$ | $$ \| $$ | $$ \$$ $$ \$$ \| $$ | $$ | $$ \$$ $$| $$
- // \$$$$$$ \$$ \$$ \$$$$$$ \$$ \$$ \$$$$ \$$$$$$$ \$$ \$$ \$$ \$$$$$$$ \$$
-
- getCountNum(params) {
- let promise = this.tim.getGroupProfile({ groupID: this.config.roomID+"" });
- promise.then(function(imResponse) {
- return imResponse.data.group.memberCount;
- console.log(imResponse.data.group);
- }).catch(function(imError) {
- console.warn('getGroupProfile error:', imError); // 获取群详细资料失败的相关信息
- });
- },
- /**
- * 初始化 IM SDK
- * @param {Object} config sdkAppID
- */
- sendGroupCustomMessage(params) {
- if (!this.tim) {
- console.warn(TAG_NAME, '未开启IM功能,该方法无法使用', params)
- return
- }
- console.log(TAG_NAME, 'sendGroupCustomMessage', params)
- const message = this.tim.createCustomMessage({
- to: params.roomID + '',
- conversationType: TIM.TYPES.CONV_GROUP,
- payload: params.payload,
- })
- const promise = this.tim.sendMessage(message)
- promise.then(function(imResponse) {
- // 发送成功
- console.log(TAG_NAME, 'sendMessage success', imResponse)
- }).catch(function(imError) {
- // 发送失败
- console.warn(TAG_NAME, 'sendMessage error:', imError)
- })
- return promise
- },
- _initIM(config,roomId) {
- if (!config.enableIM || !config.sdkAppID || this.tim) {
- return
- }
- console.log(TAG_NAME, '_initIM', config)
- // 初始化 sdk 实例
- const tim = TIM.create({
- SDKAppID: config.sdkAppID,
- })
- // 0 普通级别,日志量较多,接入时建议使用
- // 1 release级别,SDK 输出关键信息,生产环境时建议使用
- // 2 告警级别,SDK 只输出告警和错误级别的日志
- // 3 错误级别,SDK 只输出错误级别的日志
- // 4 无日志级别,SDK 将不打印任何日志
- if (config.debugMode) {
- tim.setLogLevel(1)
- } else {
- tim.setLogLevel(4)
- }
- // 取消监听
- tim.off(TIM.EVENT.SDK_READY, this._onIMReady)
- tim.off(TIM.EVENT.MESSAGE_RECEIVED, this._onIMMessageReceived)
- tim.off(TIM.EVENT.SDK_NOT_READY, this._onIMNotReady)
- tim.off(TIM.EVENT.KICKED_OUT, this._onIMKickedOut)
- tim.off(TIM.EVENT.ERROR, this._onIMError)
- // 监听事件
- tim.on(TIM.EVENT.SDK_READY, this._onIMReady, this)
- tim.on(TIM.EVENT.MESSAGE_RECEIVED, this._onIMMessageReceived, this)
- tim.on(TIM.EVENT.SDK_NOT_READY, this._onIMNotReady, this)
- tim.on(TIM.EVENT.KICKED_OUT, this._onIMKickedOut, this)
- tim.on(TIM.EVENT.ERROR, this._onIMError, this)
- this.tim = tim
- wx.tim = tim
- this._loginIM({ ...this.config, roomID: roomId })
- },
- _loginIM(params) {
- if (!this.tim) {
- return
- }
- console.log(TAG_NAME, '_loginIM', params)
- var that=this;
-
- return this.tim.login({
- userID: params.userID,
- userSig: params.userSig,
- })
- },
- _logoutIM() {
- if (!this.tim) {
- return
- }
- console.log(TAG_NAME, '_logoutIM')
- return this.tim.logout()
- },
- _exitIM() {
- this.sendGroupCustomMessage({
- roomID: Number(this.config.roomID), // 房间 ID
- payload: {
- data: 'genxin',
- description: 'genxin',
- extension: 'genxin'
- }
- })
- var that=this;
- setTimeout(function(){
- // 方法需要调用限制,否则重复解散群 退群会有warn
- if (that.config.exitIMThrottle || !that.tim) {
- return
- }
- that.config.exitIMThrottle = true
- const userList = that.getRemoteUserList()
- const roomID = that.config.roomID
- const userID = that.config.userID
- that._searchGroup({ roomID }).then((imResponse) => {
- // 查询群资料,判断是否为群主
- if (imResponse.data.group.ownerID === userID && userList.length === 0) {
- // 如果 userList 为 0 群主可以解散群,并登出IM
- that._dismissGroup({ roomID }).then(()=>{
- that.config.exitIMThrottle = false
- that._logoutIM()
- }).catch((imError) => {
- that.config.exitIMThrottle = false
- that._logoutIM()
- })
- } else if (imResponse.data.group.ownerID === userID) {
- that.config.exitIMThrottle = false
- // 群主不能退群只能登出
- that._logoutIM()
- } else {
- // 普通成员退群并登出IM
- that._quitGroup({ roomID }).then(()=>{
- that.config.exitIMThrottle = false
- that._logoutIM()
- }).catch((imError) => {
- that.config.exitIMThrottle = false
- that._logoutIM()
- })
- }
- }).catch((imError) => {
- that.config.exitIMThrottle = false
- // 查询异常直接登出
- that._logoutIM()
- })
- },2000)
- },
- _searchGroup(params) {
- if (!this.tim) {
- return
- }
- console.log(TAG_NAME, '_searchGroup', params)
- const tim = this.tim
- const promise = tim.searchGroupByID(params.roomID + '')
- promise.then(function(imResponse) {
- // const group = imResponse.data.group // 群组信息
- console.log(TAG_NAME, '_searchGroup success', imResponse)
- }).catch(function(imError) {
- console.warn(TAG_NAME, '_searchGroup fail,TIM 报错信息不影响后续逻辑,可以忽略', imError) // 搜素群组失败的相关信息
- })
- return promise
- },
- /**
- * 创建 AVchatroom
- * @param {*} params roomID
- * @returns {Promise}
- */
- _createGroup(params) {
- if (!this.tim) {
- return
- }
- console.log(TAG_NAME, '_createGroup', params)
- const promise = this.tim.createGroup({
- groupID: params.roomID + '',
- name: params.roomID + '',
- type: IM_GROUP_TYPE,
- })
- promise.then((imResponse) => { // 创建成功
- console.log(TAG_NAME, '_createGroup success', imResponse.data.group) // 创建的群的资料
- }).catch((imError) => {
- console.warn(TAG_NAME, '_createGroup error', imError) // 创建群组失败的相关信息
- })
- return promise
- },
- /**
- * 进入 AVchatroom
- * @param {*} params roomID
- * @returns {Promise}
- */
- _joinGroup(params) {
- if (!this.tim) {
- return
- }
- var that=this;
- console.log(TAG_NAME, '_joinGroup', params)
- const promise = this.tim.joinGroup({ groupID: params.roomID + '', type: IM_GROUP_TYPE })
- promise.then((imResponse) => {
- switch (imResponse.data.status) {
- case TIM.TYPES.JOIN_STATUS_WAIT_APPROVAL: // 等待管理员同意
- break
- case TIM.TYPES.JOIN_STATUS_SUCCESS: // 加群成功
- case TIM.TYPES.JOIN_STATUS_ALREADY_IN_GROUP: // 已经在群中
- // console.log(imResponse.data.group) // 加入的群组资料
- // wx.showToast({
- // title: '进群成功',
- // })
- var data={"test":"test"}
- that._emitter.emit(EVENT.IM_READY, data)
- setTimeout(function(){
- that.sendGroupCustomMessage({
- roomID: Number(that.config.roomID), // 房间 ID
- payload: {
- data: 'genxin',
- description: 'genxin',
- extension: 'genxin'
- }
- })
- },2000)
- console.log(TAG_NAME, '_joinGroup success', imResponse)
- break
- default:
- break
- }
- }).catch((imError) => {
- console.warn(TAG_NAME, 'joinGroup error', imError) // 申请加群失败的相关信息
- })
- return promise
- },
- _quitGroup(params) {
- if (!this.tim) {
- return
- }
- console.log(TAG_NAME, '_quitGroup', params)
- const promise = this.tim.quitGroup(params.roomID + '')
- promise.then((imResponse) => {
- console.log(TAG_NAME, '_quitGroup success', imResponse)
- }).catch((imError) => {
- console.warn(TAG_NAME, 'quitGroup error', imError)
- })
- return promise
- },
- _dismissGroup(params) {
- if (!this.tim) {
- return
- }
- console.log(TAG_NAME, '_dismissGroup', params)
- const promise = this.tim.dismissGroup(params.roomID + '')
- promise.then((imResponse) => {
- console.log(TAG_NAME, '_dismissGroup success', imResponse)
- }).catch((imError) => {
- console.warn(TAG_NAME, '_dismissGroup error', imError)
- })
- return promise
- },
- _onIMReady(event) {
- console.log(TAG_NAME, 'IM.READY', event)
- this._emitter.emit(EVENT.IM_READY, event)
- const roomID = this.config.roomID
- // 查询群组是否存在
- this._searchGroup({ roomID }).then((res) => {
- // console.log(TAG_NAME, 'searchGroup', res)
- // 存在直接进群
- this._joinGroup({ roomID })
- }).catch(() => {
- // 不存在则创建,如果是avchatroom 创建后进群
- this._createGroup({ roomID }).then((res) => {
- // 进群
- this._joinGroup({ roomID })
- }).catch((imError)=> {
- if (imError.code === 10021) {
- console.log(TAG_NAME, '群已存在,直接进群', event)
- this._joinGroup({ roomID })
- }
- })
- })
- // 收到离线消息和会话列表同步完毕通知,接入侧可以调用 sendMessage 等需要鉴权的接口
- // event.name - TIM.EVENT.IM_READY
- },
- _onIMMessageReceived(event) {
- // 收到推送的单聊、群聊、群提示、群系统通知的新消息,可通过遍历 event.data 获取消息列表数据并渲染到页面
- console.log(TAG_NAME, 'IM.MESSAGE_RECEIVED', event)
- // messageList 仅保留10条消息
- const messageData = event.data
- const roomID = this.config.roomID + ''
- const userID = this.config.userID + ''
- for (let i = 0; i < messageData.length; i++) {
- const message = messageData[i]
- // console.log(TAG_NAME, 'IM.MESSAGE_RECEIVED', message, this.config, TIM.TYPES.MSG_TEXT)
- if (message.to === roomID + '' || message.to === userID) {
- // 遍历messageData 获取当前room 或者当前user的消息
- console.log(TAG_NAME, 'IM.MESSAGE_RECEIVED', message, message.type, TIM.TYPES.MSG_TEXT)
- if (message.type === TIM.TYPES.MSG_TEXT) {
- /*this._pushMessageList({
- name: message.from,
- message: message.payload.text,
- })*/
- } else {
- if (message.type === TIM.TYPES.MSG_GRP_SYS_NOTICE && message.payload.operationType === 2) {
- // 群系统通知
- /*this._pushMessageList({
- name: '系统通知',
- message: `欢迎 ${userID}`,
- })*/
- }
- // 其他消息暂不处理
- }
- }
- }
- this._emitter.emit(EVENT.IM_MESSAGE_RECEIVED, event)
- },
- _onIMNotReady(event) {
- console.log(TAG_NAME, 'IM.NOT_READY', event)
- this._emitter.emit(EVENT.IM_NOT_READY, event)
- // 收到 SDK 进入 not ready 状态通知,此时 SDK 无法正常工作
- // event.name - TIM.EVENT.IM_NOT_READY
- },
- _onIMKickedOut(event) {
- console.log(TAG_NAME, 'IM.KICKED_OUT', event)
- this._emitter.emit(EVENT.IM_KICKED_OUT, event)
- // 收到被踢下线通知
- // event.name - TIM.EVENT.KICKED_OUT
- // event.data.type - 被踢下线的原因,例如 :
- // - TIM.TYPES.KICKED_OUT_MULT_ACCOUNT 多实例登录被踢
- // - TIM.TYPES.KICKED_OUT_MULT_DEVICE 多终端登录被踢
- // - TIM.TYPES.KICKED_OUT_USERSIG_EXPIRED 签名过期被踢。使用前需要将SDK版本升级至v2.4.0或以上。
- },
- _onIMError(event) {
- console.log(TAG_NAME, 'IM.ERROR', event)
- this._emitter.emit(EVENT.IM_ERROR, event)
- // 收到 SDK 发生错误通知,可以获取错误码和错误信息
- // event.name - TIM.EVENT.ERROR
- // event.data.code - 错误码
- // event.data.message - 错误信息
- }
- }
- };
- </script>
- <style>
- @import './trtc-room.css';
- </style>
|