Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Uni-APP高仿抖音|uniapp直播+小视频+聊天实例

Uni-APP高仿抖音|uniapp直播+小视频+聊天实例

原创
作者头像
andy2018
修改于 2021-09-24 03:03:24
修改于 2021-09-24 03:03:24
4K11
代码可运行
举报
文章被收录于专栏:h5h5
运行总次数:1
代码可运行

项目概况

uniapp-ttLive 一款使用uni-app+uview-ui开发的跨端短视频/直播聊天项目。

如下图:编译至小程序+h5+App端效果

采用swiper组件实现小视频上下滑动切换。支持播放/暂停。

运用技术

  • 编辑器/技术:HbuilderX3.1.21+Uniapp+Nvue+Vuex
  • UI组件库:uView-ui / uni-ui
  • 矢量图标库:iconfont字体图标
  • 弹窗组件:ua-popup 基于uni-app封装跨端弹窗组件
  • 自定义导航条+底部菜单栏
  • 编译:h5+小程序+APP端

配置main.js

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import Vue from 'vue'
import App from './App'

import uView from 'uview-ui'
Vue.use(uView)

import API from '@/common/request'
Vue.prototype.$api = API

// 引入状态管理
import Store from './store'
Vue.prototype.$store = Store

Vue.config.productionTip = false
App.mpType = 'app'

// #ifdef APP-PLUS
plus.navigator.closeSplashscreen()
// #endif

const app = new Vue({
    ...App
})
app.$mount()

项目结构目录

由于prototype不支持nvue页面,所以使用globalData全局设置状态栏高度。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<script>
	export default {
		globalData: {
			// 全局设置状态栏和导航栏高度
			statusBarH: 0,
			customBarH: 0,
		},
		onLaunch: function() {
			uni.getSystemInfo({
				success: (e) => {
					// 获取手机状态栏高度
					let statusBar = e.statusBarHeight
					let customBar
					
					// #ifndef MP
					customBar = statusBar + (e.platform == 'android' ? 50 : 45)
					// #endif
					
					// #ifdef MP-WEIXIN
					// 获取胶囊按钮的布局位置信息
					let menu = wx.getMenuButtonBoundingClientRect()
					// 导航栏高度 = 胶囊下距离 + 胶囊上距离 - 状态栏高度
					customBar = menu.bottom + menu.top - statusBar
					// #endif
					
					// #ifdef MP-ALIPAY
					customBar = statusBar + e.titleBarHeight
					// #endif
					
					// 兼容nvue写法(H5/小程序/APP/APP-Nvue)
					this.globalData.statusBarH = statusBar
					this.globalData.customBarH = customBar
				}
			})
		},
		onShow: function() {
			console.log('App Show')
		},
		onHide: function() {
			console.log('App Hide')
		}
	}
</script>

uniapp自定义组件

项目中导航条ua-navbar及底部菜单栏ua-tabbar组件,均是自定义组件。

组件支持镂空在video组件上面,实现全屏沉浸式效果。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<template>
    <view class="ua__navbar">
        <view class="ua__navbar-wrap" :class="{'custom': custom, 'fixed': fixed || transparent}"
            :style="{'height': customBarH + 'px', 'padding-top': (custom ? statusBarH : 0) + 'px', 'background': bgcolor, 'color': color, 'z-index': zIndex}">
            <!-- //左侧 (返回) -->
            <view class="action navbar-action__left" v-if="back && back!='false'" @click="onBack">
                <template v-if="$slots.back">
                    <slot name="back" />
                </template>
                <template v-else><text class="iconfont nvuefont"
                        :style="{'color': color}">{{'\ue84c'}}</text></template>
                <slot name="backText" />
            </view>
            <slot name="left" />

            <!-- //标题 -->
            <view v-if="!search" class="navbar-title" :class="{'center': center}">
                <template v-if="$slots.title">
                    <slot name="title" />
                </template>
                <template v-else><text :style="{'color': color}">{{title}}</text></template>
            </view>

            <!-- //搜索框 -->
            <view v-if="search" class="action navbar-action__search">
                <slot name="search" />
            </view>

            <!-- //右侧 -->
            <view class="action navbar-action__right">
                <slot name="right" />
            </view>
        </view>
    </view>
</template>

之前有过这方面的分享,如果感兴趣可以去看看,另外两个组件均上传至uniapp插件市场。

uniapp自定义组件uaNavbar+uaTabbar

uaPopup全新支持nvue弹窗组件

uapopup针对uniapp短视频直播项目开发的一款全端弹窗组件。

支持函数调用及组件写法调用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<ua-popup v-model="isVisibleConfirm" shadeClose="false" title="标题" xclose z-index="1001"
    content="<div style='color:#ff557f;padding:20px 40px;'>预测未来的最好办法是自己亲手创造未来!</div>"
    :btns="[
        {text: '取消', click: handleCancel},
        {text: '确定', style: 'color:#00aa00;', click: handleOk},
    ]"
/>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<script>
export default {
    methods: {
        handleOk() {
            let $ua = this.$refs.uapopup
            $ua.open({
                content: '人生漫漫,且行且珍惜',
                customStyle: {'background-color': 'rgba(170, 0, 127, 0.6)', 'color': '#fff'},
                time: 3,
                onClose() {
                    $ua.open({
                        type: 'android',
                        content: '<div style="color:#aa007f">不要等待机会,而要创造机会</div>',
                        customStyle: {'width': '210px'},
                        btns: [
                            {
                                text: '关闭',
                                click() {
                                    $ua.close()
                                }
                            },
                            {
                                text: '确定',
                                style: 'color:#00aa00;',
                                click() {
                                    // ...
                                }
                            }
                        ]
                    })
                }
            })
        }
    }
}
</script>

调用非常简单,支持20+参数混合搭配使用。

uni-app跨平台自定义弹窗组件

uni-app直播/短视频

项目中直播/短视频页面整体分为顶部导航区域、视频区域、底部菜单栏区域三个部分。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<view v-if="currentTab == 2" class="ua__tabcnt-recommend">
    <swiper class="ua__vdplayer-swiper flex1" :current="currentVideo" vertical @change="handleSwipeVertical">
        <swiper-item v-for="(item, index) in videoList" :key="index">
            <!-- 视频模块 -->
            <view class="ua__vdplayer-video flex1">
                <video class="vdplayer" :id="'vdplayer' + index" :ref="'vdplayer' + index" 
                    :src="item.src"
                    :controls="false" :loop="true" :show-center-play-btn="false" object-fit="fill"
                    :autoplay="index == currentVideo"
                    @play="isPlaying=true" @timeupdate="handleTimeUpdate"
                    :style="{'width': winWidth, 'height': winHeight}"
                >
                </video>
                <view class="ua__vdplayer-playwrap" @click="handleVideoClicked"><view v-if="!isPlaying" class="ua__vdplayer-playbtn"><text class="iconfont">{{`\ue607`}}</text></view></view>
            </view>
            <!-- 信息模块 -->
            <view class="ua__vdplayer-info flexbox flex-col">
                <view class="flexbox flex-row flex-alignb">
                    <!-- //左侧信息 -->
                    <view class="vdinfo__left flex1">
                        <view class="ltitem uavatar flexbox flex-row">
                            <navigator url="#" class="flexbox flex-alignc flex-row"><image class="uimg" :src="item.avatar" /><text class="uname">{{item.author}}</text></navigator>
                            <view class="flexbox btn" :class="{'actived': item.isFollow}" @click="handleFollow(index)"><text class="btn-text">{{item.isFollow ? '已关注' : '关注'}}</text></view>
                        </view>
                        <view v-if="item.topic" class="ltitem flexbox flex-row">
                            <view class="kw" v-for="(kw, index2) in item.topic" :key="index2"><text class="lbl">#{{kw}}</text></view>
                        </view>
                        <view class="ltitem"><text class="desc">{{item.desc}}</text></view>
                    </view>
                    <!-- //右侧按钮 -->
                    <view class="vdinfo__right flexbox flex-col">
                        <view class="rtitem ball" v-if="item.goods&&item.goods.length > 0" @click="handleShowGoodsPopup(item.goods)"><text class="icon iconfont">{{`\ue734`}}</text></view>
                        <view class="rtitem" :class="{'isliked': item.isLike}" @click="handleLiked(index)"><text class="icon iconfont">{{`\ue635`}}</text><text class="num">{{item.likeNum+(item.isLike ? 1 : 0)}}</text></view>
                        <view class="rtitem" @click="showReplyPopup = true"><text class="icon iconfont">{{`\ue632`}}</text><text class="num">{{item.replyNum}}</text></view>
                        <view class="rtitem" @click="showSharePopup = true"><text class="icon iconfont">{{`\ue63b`}}</text><text class="num">{{item.shareNum}}</text></view>
                    </view>
                </view>
            </view>
        </swiper-item>
    </swiper>
    <!-- 底部播放进度条 -->
    <view class="ua__vdplayer-progress"><view class="bar" :style="{'width': progressBar+'px'}"></view></view>
</view>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<script>
    const app = getApp()
    import videoJSON from '@/mock/videolist.js'
    
    export default {
        data() {
            return {
                // 导航栏高度
                customBarHeight: app.globalData.customBarH,
                navbarBgcolor: '#21252b',
                tabbarBgcolor: '#21252b',
                
                tabNavLs: [
                    {label: '附近动态', badge: 5, lists: []},
                    {label: '关注', lists: []},
                    {label: '推荐', dot: true, lists: []},
                ],
                // 当前选项卡
                currentTab: 0,
                
                // 当前视频索引
                currentVideo: 0,
                // 视频数据
                videoList: videoJSON,
                // 视频是否播放中
                isPlaying: false,
                // 点击次数
                clickNum: 0,
                // 视频播放进度条
                progressBar: 0,
                clickTimer: null,
                
                // 屏幕宽高
                winWidth: '',
                winHeight: '',
                
                popupGoodsList: [],
                showGoodsPopup: false,
                showReplyPopup: false,
                showSharePopup: false,
            }
        },
        watch: {
            currentTab(val) {
                this.changeTabPanel(val)
            }
        },
        computed:{
            customBarMargin() {
                return `margin-top: ${this.customBarHeight}px`
            }
        },
        created() {
            // 引入iconfont字体
            // #ifdef APP-NVUE
            const domModule = weex.requireModule('dom')
            domModule.addRule('fontFace', {
                fontFamily: "nvueIcon",
                'src': "url('/static/fonts/iconfont.ttf')"
            });
            // #endif
            
            let wW = uni.getSystemInfoSync().windowWidth
            let wH = uni.getSystemInfoSync().windowHeight
            this.winWidth = `${wW}px`
            this.winHeight = `${wH}px`
        },
        methods: {
            
            // 长按动态
            handleDynamicMenu(e) {
                let points
                // #ifndef APP-NVUE
                points = [e.touches[0].clientX, e.touches[0].clientY]
                // #endif
                // #ifdef APP-NVUE
                points = [e.touches[0].screenX, e.touches[0].screenY]
                // #endif
                
                this.$refs.uapopup.open({
                    type: 'contextmenu',
                    follow: points,
                    btns: [
                        {text: '不感兴趣'},
                        {text: '复制'},
                        {
                            text: '举报',
                            style: 'color:#f00;',
                            click: () => {
                                this.$refs.uapopup.close()
                            }
                        },
                    ],
                })
            },
            
            /* ++++++++++ { 视频播放模块 } ++++++++++ */
            getVideoCtx() {
                // return this.$refs['vdplayer' + this.currentVideo][0]
                return uni.createVideoContext('vdplayer'+ this.currentVideo, this)
            },
            
            // 垂直滑动视频
            handleSwipeVertical(e) {
                let index = e.detail.current
                this.progressBar = 0
                this.isPlaying = false
                let video = this.getVideoCtx()
                if(!video) return
                video.pause()
                // 重新开始
                video.seek(0)
                
                this.currentVideo = index
                
                // 自动播放
                this.handlePlay()
            },
            
            handlePlay() {
                let video = this.getVideoCtx()
                if(!video) return
                video.play()
                this.isPlaying = true
            },
            
            handlePause() {
                let video = this.getVideoCtx()
                if(!video) return
                video.pause()
                this.isPlaying = false
            },
            
            // 点击视频(单击/双击)
            handleVideoClicked() {
                this.clickTimer && clearTimeout(this.clickTimer)
                this.clickNum++
                this.clickTimer = setTimeout(() => {
                    if(this.clickNum >= 2) {
                        console.log('你双击了')
                    }else {
                        console.log('你单击了')
                        if(this.isPlaying) {
                            this.handlePause()
                        }else {
                            this.handlePlay()
                        }
                    }
                    this.clickNum = 0
                }, 250)
            },
            
            ...
        }
    }
</script>

另外,短视频底部有一条时间刻度进度条。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 播放进度变化时触发
handleTimeUpdate(e) {
    let { currentTime, duration } = e.detail
    
    this.progressBar = parseInt((currentTime / duration).toFixed(2) * parseInt(this.winWidth))
},

yeah,基于uniapp开发抖音短视频/直播聊天项目就分享到这里了。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
1 条评论
热度
最新
你好,界面很有很感觉了,视频编辑等SDK是用哪家的
你好,界面很有很感觉了,视频编辑等SDK是用哪家的
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
uniapp仿抖音App界面|uni-app小视频
Uni-liveshow直播室是一个基于vue+Nvue+uniapp技术开发的集仿制抖音小视频/App聊天/直播功能混合项目。可实现类似抖音上下滑动切换视频播放,支持编译到多端。
andy2018
2019/11/15
9.3K0
uniapp仿抖音App界面|uni-app小视频
uni-app自定义弹窗模板uniPop组件
uni-app自定义弹窗uniPop.vue模板|uniapp仿微信弹窗/仿ios弹窗效果|msg信息框|alert对话框|loading提示框
andy2018
2019/09/28
24K9
uni-app自定义弹窗模板uniPop组件
基于uniapp+vue3多端h5+小程序+App端直播商城
uniapp-welive一款基于uni-app+vue3+pinia+vk-uview等技术搭建跨端仿抖音直播商城项目。
andy2018
2024/01/02
8390
uni-app开发一个小视频应用(二)
“ 前情回顾uni-app开发一个小视频应用(一)上篇文章,我们已经实现了首页的头部导航栏组件、底部的tabBar导航栏组件、中间的视频列表组件以及视频列表组件中的视频播放组件,传入视频列表渲染后已经可以上下滑动进行视频切换和播放,接下来我们将完成首页的剩余部分,左侧信息栏组件、右侧图标栏组件,以及完善视频切换动画、播放控制等功能。 ” 一 创建左侧信息栏组件 左侧的信息栏组件,主要分三块: 作者名、视频标题名、音乐名。这个左侧信息栏信息是和当前播放视频相关联的,所以应该在循环视频列表的时候,将左侧信息
腾讯NEXT学位
2019/10/21
1.7K0
uni-app开发一个小视频应用(二)
uni-app实战之社区交友APP(8)搜索列表页和文章详情页开发
本文先介绍了搜索结果页开发,包括搜索类型的传递、占位符设置和搜索功能实现; 再介绍了帖子详情页的开发,包括页面配置和通信、公共列表组件优化、关注顶踩功能完善、帖子内容和图片展示、评论输入框组件开发和封装、评论列表组件和分享功能组件开发等。
cutercorley
2021/02/04
2.4K0
uni-app实战之社区交友APP(8)搜索列表页和文章详情页开发
uni-app+vue3+pinia小程序/App/H5端chatgpt实例
给大家分享一个最新研发的uniapp+vue3跨多个平台仿制chatGPT会话应用项目。
andy2018
2023/06/28
1.7K1
uni-app实战之社区交友APP(9)我的页面开发
本文主要介绍了我的(个人中心)页面开发,包括以下几方面: 个人中心和设置页面开发,包括页面配置、个人中心和设置页UI构建; 修改密码和邮箱页面开发,包括修改密码UI构建和表单验证、修改邮箱UI构建和表单验证; 编辑资料页面开发,包括页面UI构建、修改头像、昵称、性别、情感、职业、生日和城市功能实现; 帮助反馈和关于页面开发。
cutercorley
2021/02/22
2.7K1
uni-app实战之社区交友APP(9)我的页面开发
Electron+Vite2整合开发vue3.0直播/聊天/小视频应用
前段时间有给大家分享一个Electron跨端仿QQ聊天,今天带来最新研发的Electron短视频|直播应用。
andy2018
2021/03/28
2.3K0
Electron+Vite2整合开发vue3.0直播/聊天/小视频应用
tauri聊天应用篇|vue3+tauri桌面聊天实例
前几天有分享一篇tauri整合vue3.js创建多窗口应用,tauri封装多开窗体。
andy2018
2022/10/29
4.4K1
uni-app实战之社区交友APP(4)首页开发
本文主要介绍了首页图文列表和滚动选项卡的开发: 图文列表的开发,包括顶部导航栏配置,图文列表项(头像、昵称、关注按钮、标题、标题封面图、点赞、踩、评论和分享)等的开发; 列表组件优化,包括分割线的开发和封装,动画特效实现,关注、顶踩功能的完善; 滚动选项卡开发,包括顶部选项卡开发、列表的同步显示和滑动,上拉加载的开发和封装,无数据组件开发等。
cutercorley
2021/01/29
2.8K0
uni-app实战之社区交友APP(4)首页开发
全新Uniapp+uniUI后台管理uniUadmin
新年的鞭炮声又响了,拉开窗帘一看,外面依然漆黑一片,好了,反正都醒了,就暂且起来吧。零下几度的天气有些冷,就批件衣服先醒醒吧。就想着写些什么呢,突然想到最近开发了一款uni-app后台管理系统模板,就来分享下吧。
andy2018
2022/01/31
2.4K1
uni-app小程序开发-组件
https://hellouniapp.dcloud.net.cn/pages/component/view/view
码客说
2024/07/22
1590
uni-app+vue仿微信聊天APP界面|uniapp仿微信朋友圈
基于uniapp+vue仿微信聊天室uniapp-chatroom项目,vue语法及类似小程序api开发原生APP应用,实现了发送图文消息、表情(gif动图),图片预览、地图位置、红包、仿微信朋友圈等功能。
andy2018
2019/10/10
10.6K3
uni-app+vue仿微信聊天APP界面|uniapp仿微信朋友圈
uniapp-vue3-wechat聊天实例|uni-app+pinia2仿微信app
Uniapp_Vue3_Chat基于uni-app+vue3+pinia2+uv-ui跨三端(h5+小程序+APP端)仿微信聊天。
andy2018
2024/04/29
6770
Electron跨平台仿QQ|vue3+electron+antdv聊天应用
此前有给大家分享一个vite2+vant3开发h5手机端小视频实例。今分享一个最新开发的electron跨端聊天应用。
andy2018
2021/02/27
2.6K3
Electron跨平台仿QQ|vue3+electron+antdv聊天应用
原创uniapp+vue3+pinia仿ios桌面后台OA管理系统
vue3-uni-weos:一款基于uniapp+vite5.x+pinia搭建手机端后台OA管理模板项目。
andy2018
2024/05/22
4111
原创uniapp+vue3+pinia仿ios桌面后台OA管理系统
vue+web端聊天室|网页端vue聊天系统
使用了Vue2.5.6+Vuex+vue-router+vue-gemini-scrollbar+swiper+elementUI等技术开发,实现了发送消息、表情(动图),图片、视频预览,仿微信右键菜单、截图可直接粘贴至编辑框发送。
andy2018
2019/05/01
11.8K1
vue+web端聊天室|网页端vue聊天系统
Vue3.0+Vant3移动端短视频+聊天+直播实战
随着人们生活品质的提高,5G及手机硬件的快速发展,短视频/直播快速的成为了很多人的娱乐方式。
andy2018
2021/02/03
4.8K1
Vue3.0+Vant3移动端短视频+聊天+直播实战
第三章:组织页面完善、引入消息帖子与页面独立状态
Qiuner
2024/11/21
690
第三章:组织页面完善、引入消息帖子与页面独立状态
uni-app开发一个小视频应用(一)
“ uni-app 是一个使用 Vue.js 开发所有前端应用的框架,是一种终极的跨平台解决方案,这里的平台,主要指的是App平台(android、ios)、小程序平台、H5平台。开发者编写一套代码,可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台。 ” 01 开发一个小视频应用 一 初始化项目 打开HBuilderX IDE,新建一个名称为mini-video的初始化uni-app项目,这里勾选uni-app即可创建,项目创建完成后,打开pages
腾讯NEXT学位
2019/10/12
3.9K0
uni-app开发一个小视频应用(一)
相关推荐
uniapp仿抖音App界面|uni-app小视频
更多 >
LV.1
这个人很懒,什么都没有留下~
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验