| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745 |
- <template>
- <view class="container">
- <view class="top">
- <view id="aliplay" class="course-video" v-if="liveInfo.is_play"></view>
- <view class="course-video errorContent" v-else @touchmove.prevent ref="column">
- <view class="contentText">
- <image class="tvImg" src="../../static/img/tv.png" mode="widthFix"></image>
- <view v-if="liveInfo.live_status == 0">直播即将开始</view>
- <view v-else-if="liveInfo.live_status == 2">直播已结束</view>
- <view v-else-if="liveInfo.live_status == 1">讲师离开一会~马上回来</view>
- <view v-else-if="liveInfo.live_status == -1" v-text="live_error">讲师离开一会~马上回来</view>
- </view>
- </view>
- </view>
- <view class="uni-column">
- <view class="content" id="content" :style="{ height: style.contentViewHeight + 'px' }">
- <scroll-view
- id="scrollview"
- class="Meslist"
- :scroll-y="true"
- :style="{ height: style.contentViewHeight + 'px' }"
- :scroll-with-animation="true"
- :scroll-top="scrollTop"
- >
- <view id="listBox">
- <view v-for="(ls, index) in MsgList" :key="index">
- <view class="m-item" :id="'message' + index">
- <view class="m-left"><image class="head_icon" :src="ls.avatar" v-if="ls.uid != userInfo.uid"></image></view>
- <view class="m-content">
- <view class="m-content-head" :class="{ 'm-content-head-right': ls.uid == userInfo.uid }">
- <view :class="'m-content-head-' + 'home'" v-if="ls.uid == userInfo.uid">
- <rich-text :nodes="ls.content.replace(reg, emotion)"></rich-text>
- </view>
- <view :class="'m-content-head-' + 'customer'" v-if="ls.uid != userInfo.uid">
- <rich-text :nodes="ls.content.replace(reg, emotion)"></rich-text>
- </view>
- </view>
- </view>
- <view class="m-right"><image class="head_icon" :src="userInfo.avatar" v-if="ls.uid == userInfo.uid"></image></view>
- </view>
- </view>
- </view>
- </scroll-view>
- </view>
- <view class="foot">
- <view class="footheight">
- <view class="footer">
- <view class="footer-emotion" @tap="show"><text class="icon iconfont icon-face"></text></view>
- <view class="footer-center"><input class="input-text" placeholder="清输入您的信息" type="text" v-model="inputValue" @focus="foc" :focus="focus" /></view>
- <view class="footer-right" @tap="sendMessge">
- <view id="msg-type"><image src="/static/img/img024.png"></image></view>
- </view>
- </view>
- <emotion @emotion="handleEmotion" :height="200" v-if="showPannel"></emotion>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import { mapState, mapMutations } from 'vuex';
- import messageShow from '@/components/imchat-emoji/messageshow.vue';
- import Emotion from '@/components/imchat-emoji/Emotion/index.vue';
- import { liveList } from '@/api/live.js';
- // #ifdef H5
- import { getWwwJs } from '@/utils/rocessor.js';
- // #endif
- export default {
- components: {
- messageShow,
- Emotion
- },
- data() {
- return {
- live_id: '', //直播id
- special_id: '', //专题id
- style: {
- pageHeight: 0,
- contentViewHeight: 0,
- footViewHeight: 90,
- mitemHeight: 0
- },
- scrollTop: 0,
- messages: '', //消息内容
- inputValue: '', //输入框内容
- showPannel: false,
- focus: false,
- // socketTask: null,
- socketOpen: false,
- reg: /\#[\S]{1,3}\;/gi,
- PullUrl: '',
- socketTask: '', //保存长连接会话
- player: '', //绑定播放器
- // 直播详情
- liveInfo: {
- is_play: false
- },
- MsgList: []
- };
- },
- computed: {
- ...mapState(['userInfo'])
- },
- onLoad: function(option) {
- this.info(option);
- },
- methods: {
- info(option) {
- let obj = this;
- obj.live_id = option.live_id;
- obj.special_id = option.special_id;
- const res = uni.getSystemInfoSync();
- obj.style.pageHeight = res.windowHeight;
- obj.style.contentViewHeight = res.windowHeight - (uni.getSystemInfoSync().screenWidth / 750) * 620; //像素
- obj.connectSocketInit();
- obj.loadDate().then(e => {
- obj.$nextTick(function() {
- // #ifdef H5
- // 加載網絡js資源
- obj.aliPlayShow();
- // #endif
- });
- });
- },
- // #ifdef H5
- // 渲染播放器
- aliPlayShow() {
- this.player = new Aliplayer(
- {
- id: 'aliplay',
- source: this.PullUrl,
- width: '100%',
- height: '56.25vw',
- autoplay: true,
- isLive: true,
- rePlay: false,
- playsinline: true,
- preload: true,
- autoPlayDelay: '',
- controlBarVisibility: 'hover',
- useH5Prism: true,
- skinLayout: [
- {
- name: 'errorDisplay',
- align: 'tlabs',
- x: 0,
- y: 0
- },
- {
- name: 'infoDisplay'
- },
- {
- name: 'controlBar',
- align: 'blabs',
- x: 0,
- y: 0,
- children: [
- {
- name: 'liveDisplay',
- align: 'tlabs',
- x: 15,
- y: 6
- },
- {
- name: 'fullScreenButton',
- align: 'tr',
- x: 10,
- y: 10
- },
- {
- name: 'volume',
- align: 'tr',
- x: 5,
- y: 10
- }
- ]
- }
- ]
- },
- function(player) {
- console.log('The player is created');
- }
- );
- this.bindEvevt();
- },
- // #endif
- /*
- * 播放器错误事件处理
- *
- * */
- bindEvevt: function() {
- var that = this;
- this.player.on('onM3u8Retry', function() {
- if (that.player) that.player.dispose();
- that.live_error = '主播暂时离开,请稍后.';
- that.live_status = -1;
- that.liveInfo.is_play = false;
- console.log('主播暂时离开,请稍后......');
- });
- this.player.on('liveStreamStop', function() {
- console.log('直播失败或直播已结束');
- that.live_error = '直播失败或直播已结束';
- that.live_status = -1;
- that.liveInfo.is_play = false;
- if (that.player) that.player.dispose();
- });
- this.player.on('error', function(e) {
- //隐藏
- $('.prism-ErrorMessage').hide();
- //解析
- var errorData = e.paramData;
- that.live_error = '直播失败或直播已结束';
- that.live_status = -1;
- that.liveInfo.is_play = false;
- if (that.player) that.player.dispose();
- });
- },
- //创建一个 WebSocket 连接。
- connectSocketInit() {
- let obj = this;
- obj.socketTask = uni.connectSocket({
- url: 'ws://doctortest.igxys.com:20014',
- success(data) {
- console.log('websocket连接成功');
- }
- });
- // 开始打开链接监听
- obj.socketTask.onOpen(res => {
- console.log('WebSocket连接正常打开中...!');
- obj.socketOpen = true;
- // 注:只有连接正常打开中 ,才能正常收到消息
- obj.socketTask.onMessage(res => {
- console.log('监听返回事件');
- // 保存返回类型处理
- let data = JSON.parse(res.data);
- obj.messageType(data, 'live_ing').then(() => {
- location.reload();
- });
- if(data.type == 'message'){
- console.log(data,'data')
- let message={
- avatar:data.userInfo.avatar,
- content:data.message,
- nickname:data.userInfo.nickname,
- type:data.m_type,
- uid:data.userInfo.uid,
- }
- this.MsgList = this.MsgList.concat(message);
- console.log(this.MsgList)
- }
- obj.$nextTick(function() {
- obj.scrollToBottom();
- });
- });
- // 进入房间
- let join = `{"type":"handshake","role":"user","uid": "${obj.userInfo.uid}","room":"${obj.live_id}"}`;
- obj.socketTask.send({
- data: join,
- success: res => {
- console.log('初始化消息发送成功');
- }
- });
- });
- },
- // 处理判断监听回收类型
- messageType(res, type) {
- console.log(res);
- console.log(res.type, type);
- return new Promise((ok, error) => {
- if (res.type == type) {
- ok(true);
- }
- });
- },
- sendMessge: function() {
- var obj = this;
- if (obj.inputValue.trim() == '') {
- obj.inputValue = '';
- } else {
- //点击发送按钮
- this.getInputMessage(obj.inputValue);
- obj.inputValue = '';
- this.showPannel = false;
- }
- },
- //获取输入框数据
- getInputMessage: function(message) {
- let obj = this;
- if (obj.socketOpen) {
- let msg = `{"content":"${message}","m_type":"1","type":"send","room":"${this.live_id}"}`;
- console.log(msg);
- obj.socketTask.send({
- data: msg,
- success: res => {
- let newmessage = JSON.parse(msg);
- console.log('输入框消息发送成功');
- console.log(newmessage);
- // obj.MsgList = obj.MsgList.concat(mes);
- obj.$nextTick(function() {
- obj.scrollToBottom();
- });
- },
- fail: err => {
- console.log(err);
- }
- });
- } else {
- obj.messages = message;
- }
- obj.setScrollH();
- },
- scrollToBottom: function() {
- //哪里需要用到就在哪里使用
- let obj = this;
- let query = uni.createSelectorQuery().in(this);
- query
- .select('#listBox')
- .fields(
- {
- dataset: true,
- size: true,
- scrollOffset: true,
- rect: true
- },
- function(res) {
- obj.scrollTop = res.height;
- }
- )
- .exec();
- },
- // 设置高度 用emit辅助
- setScrollH: function() {
- let screenHeight = uni.getSystemInfoSync().windowHeight; //获取屏幕高度
- // 通过query 获取其余盒子的高度
- let query = uni.createSelectorQuery().in(this);
- query.select('.foot').boundingClientRect();
- // 通过query.exec返回的数组 进行减法 同时 去除margin 和border的
- query.exec(res => {
- let foot = res[0].height;
- screenHeight = screenHeight - foot;
- });
- },
- // 关闭websocket【离开这个页面的时候执行关闭】
- closeSocket() {
- this.socketTask.close({
- success(res) {
- this.socketOpen = false;
- console.log('关闭成功', res);
- },
- fail(err) {
- console.log('关闭失败', err);
- }
- });
- },
- loadDate() {
- let obj = this;
- return new Promise(function(resolve, reject) {
- liveList({
- special_id: obj.special_id,
- live_id: obj.live_id
- })
- .then(({ data }) => {
- obj.liveInfo = data.liveInfo;
- obj.liveInfo.is_play = obj.liveInfo.is_play == 1 ? true : false;
- obj.PullUrl = data.PullUrl;
- // 保存播放状态
- obj.liveInfo.live_status = data.live_status;
- resolve(data);
- obj.$nextTick(function() {
- obj.scrollToBottom();
- });
- })
- .catch(e => {
- reject(e.message);
- if(e.message == '您还没有支付请支付后再进行观看'){
- uni.navigateTo({
- url:'/pages/live/details?id='+obj.special_id+'&type=free'
- })
- }
- });
- });
- },
- //语音识别
- // startRecognize: function() {
- // var options = {};
- // var that = this;
- // options.engine = 'iFly';
- // that.inputValue = '';
- // plus.speech.startRecognize(
- // options,
- // function(s) {
- // console.log(s);
- // that.inputValue += s;
- // },
- // function(e) {
- // console.log('语音识别失败:' + e.message);
- // }
- // );
- // },
- show() {
- this.showPannel = !this.showPannel;
- },
- // 光标触发隐藏表情
- foc() {
- this.showPannel = false;
- },
- handleEmotion(i) {
- this.inputValue += i;
- },
- emotion(res) {
- let word = res.replace(/\#|\;/gi, '');
- const list = [
- '微笑',
- '撇嘴',
- '色',
- '发呆',
- '得意',
- '流泪',
- '害羞',
- '闭嘴',
- '睡',
- '大哭',
- '尴尬',
- '发怒',
- '调皮',
- '呲牙',
- '惊讶',
- '难过',
- '酷',
- '冷汗',
- '抓狂',
- '吐',
- '偷笑',
- '可爱',
- '白眼',
- '傲慢',
- '饥饿',
- '困',
- '惊恐',
- '流汗',
- '憨笑',
- '大兵',
- '奋斗',
- '咒骂',
- '疑问',
- '嘘',
- '晕',
- '折磨',
- '衰',
- '骷髅',
- '敲打',
- '再见',
- '擦汗',
- '抠鼻',
- '鼓掌',
- '糗大了',
- '坏笑',
- '左哼哼',
- '右哼哼',
- '哈欠',
- '鄙视',
- '委屈',
- '快哭了',
- '阴险',
- '亲亲',
- '吓',
- '可怜',
- '菜刀',
- '西瓜',
- '啤酒',
- '篮球',
- '乒乓',
- '咖啡',
- '饭',
- '猪头',
- '玫瑰',
- '凋谢',
- '示爱',
- '爱心',
- '心碎',
- '蛋糕',
- '闪电',
- '炸弹',
- '刀',
- '足球',
- '瓢虫',
- '便便',
- '月亮',
- '太阳',
- '礼物',
- '拥抱',
- '强',
- '弱',
- '握手',
- '胜利',
- '抱拳',
- '勾引',
- '拳头',
- '差劲',
- '爱你',
- 'NO',
- 'OK',
- '爱情',
- '飞吻',
- '跳跳',
- '发抖',
- '怄火',
- '转圈',
- '磕头',
- '回头',
- '跳绳',
- '挥手',
- '激动',
- '街舞',
- '献吻',
- '左太极',
- '右太极'
- ];
- let index = list.indexOf(word);
- return `<img src="https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/${index}.gif" align="middle">`;
- }
- }
- };
- </script>
- <!-- #ifdef H5 -->
- <style lang="postcss" scoped>
- @import 'https://g.alicdn.com/de/prismplayer/2.7.2/skins/default/aliplayer-min.css';
- </style>
- <!-- #endif -->
- <style lang="scss">
- .container{
- background-color: #FFFFFF;
- }
- //视频
- .top {
- width: 100%;
- height: 500rpx;
- .course-video {
- width: 100%;
- height: 60vw;
- &.errorContent {
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: #212121;
- text-align: center;
- .contentText {
- font-size: $font-lg;
- color: #ffffff;
- .tvImg {
- width: 75rpx;
- height: 64rpx;
- margin-bottom: 25rpx;
- }
- }
- }
- }
- }
- .uni-column {
- display: flex;
- flex-direction: column;
- }
- .content {
- display: flex;
- flex: 1;
- /* margin-bottom: 100upx; */
- }
- .foot {
- box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.1);
- position: fixed;
- width: 100%;
- height: auto;
- left: 0upx;
- bottom: 0;
- overflow: hidden;
- }
- .footer {
- display: flex;
- flex-direction: row;
- width: 100%;
- height: 110rpx;
- line-height: 100rpx;
- overflow: hidden;
- background-color: #ffffff;
- }
- .footer-left {
- width: 80upx;
- height: 80upx;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .footer-right {
- background-color: #6786fb;
- width: 130rpx;
- display: flex;
- justify-content: center;
- align-items: center;
- color: #1482d1;
- line-height: 20rpx;
- image {
- width: 50rpx;
- height: 50rpx;
- }
- }
- .footer-emotion {
- padding: 0rpx 25rpx;
- display: flex;
- justify-content: flex-end;
- align-items: center;
- color: #1482d1;
- }
- .footer-center {
- border-left: 2rpx solid #cccccc;
- padding-left: 20rpx;
- flex: 1;
- display: flex;
- justify-content: center;
- align-items: center;
- font-size: 26rpx;
- }
- .footer-center .input-text {
- font-size: 26rpx;
- flex: 1;
- background: #fff;
- font-family: verdana !important;
- overflow: hidden;
- border-radius: 15upx;
- }
- @font-face {
- font-family: 'iconfont';
- /* project id 1134039 */
- src: url('http://at.alicdn.com/t/font_1134039_uait6xu86bf.eot');
- src: url('http://at.alicdn.com/t/font_1134039_uait6xu86bf.eot?#iefix') format('embedded-opentype'), url('http://at.alicdn.com/t/font_1134039_uait6xu86bf.woff2') format('woff2'),
- url('http://at.alicdn.com/t/font_1134039_uait6xu86bf.woff') format('woff'), url('http://at.alicdn.com/t/font_1134039_uait6xu86bf.ttf') format('truetype'),
- url('http://at.alicdn.com/t/font_1134039_uait6xu86bf.svg#iconfont') format('svg');
- }
- .iconfont {
- font-family: 'iconfont' !important;
- font-size: 18px;
- font-style: normal;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- }
- .icon {
- color: #f3b72c !important;
- }
- .icon-face:before {
- content: '\e71c';
- font-size: 50upx;
- }
- .m-item {
- display: flex;
- flex-direction: row;
- padding-top: 40upx;
- }
- .m-left {
- display: flex;
- width: 120upx;
- justify-content: center;
- align-items: flex-start;
- }
- .m-content {
- display: flex;
- flex: 1;
- flex-direction: column;
- justify-content: center;
- word-break: break-all;
- font-size: 22rpx;
- }
- .m-right {
- display: flex;
- width: 120upx;
- justify-content: center;
- align-items: flex-start;
- }
- .head_icon {
- width: 80upx;
- height: 80upx;
- border-radius: 100%;
- }
- .m-content-head {
- position: relative;
- }
- .m-content-head-right {
- display: flex;
- justify-content: flex-end;
- }
- .m-content-head-customer {
- text-align: left;
- background: #f7f7fb;
- border: 1px #f7f7fb solid;
- border-radius: 20upx;
- padding: 20upx 25rpx;
- font-size: 26rpx !important;
- display: inline-block;
- }
- .m-content-head-customer:before {
- border: 15upx solid transparent;
- border-right: 15upx solid #f7f7fb;
- left: -26upx;
- width: 0;
- height: 0;
- position: absolute;
- content: ' ';
- }
- .m-content-head-home {
- border: 1upx white solid;
- font-size: 26rpx !important;
- background: white;
- border-radius: 20upx;
- padding: 20upx;
- background-color: #f7f7fb;
- }
- .m-content-head-home:after {
- border: 15upx solid transparent;
- border-left: 15upx solid #f7f7fb;
- top: 20upx;
- right: -26upx;
- width: 0;
- height: 0;
- position: absolute;
- content: ' ';
- }
- </style>
|