关于全栈项目【臻美短视频】总结

小灰灰 2021-08-13 17:47 417阅读 0赞

登录注册页
在这里插入图片描述
视频展示页
在这里插入图片描述
上传拍摄视频页
在这里插入图片描述
以上是臻美短视频的基本页面。

这个项目的有几大难点:

一、登录注册功能的实现

二、视频数据的实时获取以及上滑切换视频

三、上传视频以及录制视频


那么我们一步一步分析

一、登录注册功能的实现

这里后台使用的是nodejs,调用相应的端口就可以存入数据库。

在这里插入图片描述

  1. var express = require('express')
  2. var multer = require('multer')
  3. var jwt = require('jsonwebtoken');
  4. var mysql = require('mysql');
  5. var bodyParser = require('body-parser')
  6. // 如果使用POST方法,就必须导入bodyParser,body-parser请求体解析模块,是express的中间件用于接受请求体中的数据,并解析为对象,解析之后的对象会将作为body属性添加给rep对象
  7. var fs = require('fs');
  8. var join = require('path').join;
  9. var web = express();
  10. var secretkey = 'secretkey';
  11. var connection = mysql.createConnection({
  12. host: 'localhost',
  13. user: 'root',
  14. password: '',
  15. port: '3306',
  16. database: 'sv'
  17. });
  18. connection.connect();
  19. web.use(express.static('public'))
  20. // 设置服务器静态文件夹,里面的文件都是呈现给人们看的网页
  21. web.use(bodyParser.json());
  22. web.use(bodyParser.urlencoded({
  23. extended: true
  24. }));
  25. web.all("*", function (req, res, next) {
  26. res.header('Access-Control-Allow-Origin', req.headers.origin || '*');
  27. res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length, Authorization,\'Origin\',Accept,X-Requested-With');
  28. res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
  29. res.header('Access-Control-Allow-Credentials', true);
  30. res.header('X-Powered-By', ' 3.2.1');
  31. res.header('Content-Type', 'application/json;charset=utf-8');
  32. if (req.method.toLowerCase() == 'options')
  33. res.send(200); //让options尝试请求快速结束
  34. else
  35. next();
  36. })
  37. //用户登录
  38. web.post('/user/login', (req, res) => {
  39. var name = req.body.username;
  40. var passwd = req.body.password;
  41. var userStr = `select username,password,token from user where username="${ name}" and password="${ passwd}"`;
  42. connection.query(userStr, function (err, result) {
  43. if (err) {
  44. throw err;
  45. } else {
  46. res.json({
  47. message: result,
  48. })
  49. }
  50. })
  51. })
  52. //符合
  53. web.post('/user/accord', (req, res) => {
  54. var token2 = req.body.token1;
  55. var userStr = `select username,token from user where token="${ token2}"`;
  56. connection.query(userStr, function (err, result) {
  57. if (err) {
  58. throw err;
  59. } else {
  60. res.json({
  61. message: result,
  62. })
  63. }
  64. })
  65. })
  66. //用户注册
  67. web.post('/user/register', (req, res) => {
  68. var name = req.body.username;
  69. var passwd = req.body.password;
  70. var token1 = jwt.sign({
  71. username: name
  72. }, secretkey, {
  73. expiresIn: 60 * 8
  74. });
  75. var json = { };
  76. var userStr = `select * from user where username="${ name}"`;
  77. connection.query(userStr, function (err, result) {
  78. if (err) throw err;
  79. if (result.length > 0) {
  80. json.message = '用户已经存在';
  81. json.resultCode = 1;
  82. } else {
  83. json.message = '注册成功';
  84. json.token = token1;
  85. json.resultCode = 200;
  86. var insertStr = `insert into user (username, password,token) values ("${ name}", "${ passwd}","${ token1}")`;
  87. console.log(insertStr)
  88. connection.query(insertStr, function (err, res) {
  89. if (err) throw err;
  90. })
  91. }
  92. res.send(JSON.stringify(json))
  93. })
  94. })
  95. var fullName = '';
  96. var pa="";
  97. var y1="";
  98. var i=0;
  99. var userq=''
  100. web.post('/username', function (req, res) {
  101. // res.send('')
  102. userq = req.body.name;
  103. console.log(userq)
  104. })
  105. var headerConfig = multer.diskStorage({
  106. // destination目的地
  107. destination: 'public/video',
  108. filename: function (req, file, cb) {
  109. var fileFormat = (file.originalname).split(".");
  110. cb(null, userq + '-' + Date.now() + "." + fileFormat[fileFormat.length - 1]);
  111. }
  112. })
  113. var upload = multer({
  114. storage: headerConfig
  115. })
  116. function getJsonFiles(jsonPath) {
  117. let jsonFiles = [];
  118. function findJsonFile(path) {
  119. let files = fs.readdirSync(path);
  120. files.forEach(function (item, index) {
  121. let fPath = join(path, item);
  122. let stat = fs.statSync(fPath);
  123. if (stat.isDirectory() === true) {
  124. findJsonFile(fPath);
  125. }
  126. if (stat.isFile() === true) {
  127. let fail = fPath.slice(7);
  128. jsonFiles.push('https://www.xxx.cn/xxx/' + fail);
  129. }
  130. });
  131. }
  132. findJsonFile(jsonPath);
  133. // console.log(jsonFiles);
  134. pa = jsonFiles;
  135. }
  136. web.post('/upload',upload.single('video'), function (req, res) {
  137. // res.send('')
  138. console.log('上传成功')
  139. })
  140. web.get('/video', function (req, res) {
  141. getJsonFiles("./public/video");
  142. res.send(pa);
  143. })
  144. web.listen('7500', function () {
  145. console.log('服务器开启')
  146. })

前台使用的是Vue,UI框架Vant。前台比较简单,这里不多过叙述。

  1. <template>
  2. <div>
  3. <div class="logo"><img src="../assets/video.png" alt=""></div>
  4. <van-cell-group class="int">
  5. <van-field v-model="username" clearable label="用户名" placeholder="请输入用户名" maxlength="6" clickable />
  6. <van-field v-model="password" type="password" label="密码" maxlength="6" placeholder="请输入密码" clickable />
  7. </van-cell-group>
  8. <div class="foot">
  9. <van-button type="primary" color="#00CED1" class="login" @click="log" >登录</van-button>
  10. <p class="reg" @click="reg">注册</p>
  11. </div>
  12. </div>
  13. </template>
  14. <script>import md5 from 'js-md5' const delay = (function () { let timer = 0 return function (callback, ms) { clearTimeout(timer) timer = setTimeout(callback, ms) } })() export default { name: 'login', data () { return { username: '', password: '', sse: '' } }, methods: { reg () { if (this.username.length !== 0 && this.password.length !== 0) { delay(() => { let postData = { username: this.username, password: md5(this.password) } this.$axios.post('https://xxx/xxxx/user/register', postData) .then((response) => { // success console.log(response.data) if (response.data.resultCode === 200) { this.$notify({ message: response.data.message, duration: 1000, background: '#07C160' }) this.username = '' this.password = '' } else if (response.data.resultCode === 1) { this.$notify({ message: response.data.message, duration: 1000, background: '#FFA500' }) } }) .catch((error) => { // error console.log(error) }) }, 500) } else { this.$notify({ message: '注册失败!', duration: 1000, background: '#FF0000' }) } }, log () { delay(() => { let postData = { username: this.username, password: md5(this.password) } this.$axios.post('https://xxx/xxx/user/login', postData) .then((response) => { // success console.log(response.data.message) if (response.data.message.length === 0) { // ('登录失败') this.$notify({ message: '登录失败!', duration: 1000, background: '#FF0000' }) } else { localStorage.setItem('svuser', response.data.message[0].token) localStorage.setItem('svdata', JSON.stringify(response.data.message[0])) this.$router.push({ name: 'index' }) this.$notify({ message: '登录成功!', duration: 1000, background: '#07C160' }) } }) .catch((error) => { // error console.log(error) }) }, 500) } } } </script>

二、视频数据的实时获取以及上滑切换视频

视频获取直接调用接口就可以了

  1. <template>
  2. <div class="index">
  3. <div class="close" @click="close">
  4. <div>
  5. <van-icon name="cross" color="#00CED1"/>
  6. </div>
  7. </div>
  8. <van-swipe style="height: 100vh;" vertical :show-indicators="false" @change="onChange" touchable>
  9. <van-swipe-item v-for="(item,index) in list" :key="index">
  10. <div class="main" v-if="playIndex==index">
  11. <video loop :src="item" preload autoplay="autoplay" controls="controls"></video>
  12. <div class="foot">
  13. <p class="name">@ {
  14. { item | capitalize }}</p>
  15. </div>
  16. </div>
  17. </van-swipe-item>
  18. </van-swipe>
  19. <div class="add">
  20. <div @click="b1()">
  21. <van-button icon="plus" color="#00CED1" />
  22. </div>
  23. </div>
  24. </div>
  25. </template>
  26. <script> export default { name: 'index', data () { return { current: 0, list: '', playIndex: 0 } }, methods: { close () { this.$notify({ message: '退出成功!', duration: 1000, background: '#07C160' }) setTimeout(() => { localStorage.clear() window.location.reload() }, 1000) }, onChange (index) { this.current = index this.playIndex = index console.log(index) }, b1 () { const data1 = JSON.parse(localStorage.getItem('svdata')) this.$router.push({ name: 'upload', params: { name: data1.username } }) } }, filters: { capitalize: function (value) { // console.log(value.slice(39)) let a = value.slice(39) return a.split('-')[0] } }, mounted () { // location.reload() // document.querySelector('video').playbackRate = 0.75 const data1 = JSON.parse(localStorage.getItem('svdata')) if (data1.token === localStorage.getItem('svuser')) { // this.name = data1.username this.$axios.get('https://xxx/xxx/video/') .then((response) => { // success console.log(response.data) this.list = response.data }) .catch((error) => { // error console.log(error) }) } } } </script>

三、上传视频以及录制视频

这里使用的是node的multer模块

  1. var fullName = '';
  2. var pa="";
  3. var y1="";
  4. var i=0;
  5. var userq=''
  6. web.post('/username', function (req, res) {
  7. // res.send('')
  8. userq = req.body.name;
  9. console.log(userq)
  10. })
  11. // 思路
  12. // 上传内容并储存——1.设置存储的地方——2.设置存储时的名字{1.获取原来名字的后缀,2.再重新命名}
  13. var headerConfig = multer.diskStorage({
  14. // destination目的地
  15. destination: 'public/video',
  16. // fliename 文件名 后面跟函数,函数有三个参数
  17. // file为当前上传的文件
  18. filename: function (req, file, cb) {
  19. var fileFormat = (file.originalname).split(".");
  20. cb(null, userq + '-' + Date.now() + "." + fileFormat[fileFormat.length - 1]);
  21. }
  22. })
  23. // 设置使用当前的配置信息
  24. // 上传完照片后要使用的配置信息
  25. var upload = multer({
  26. storage: headerConfig
  27. })
  28. function getJsonFiles(jsonPath) {
  29. let jsonFiles = [];
  30. function findJsonFile(path) {
  31. let files = fs.readdirSync(path);
  32. files.forEach(function (item, index) {
  33. let fPath = join(path, item);
  34. let stat = fs.statSync(fPath);
  35. if (stat.isDirectory() === true) {
  36. findJsonFile(fPath);
  37. }
  38. if (stat.isFile() === true) {
  39. let fail = fPath.slice(7);
  40. jsonFiles.push('https://xxx/xxx/' + fail);
  41. }
  42. });
  43. }
  44. findJsonFile(jsonPath);
  45. // console.log(jsonFiles);
  46. pa = jsonFiles;
  47. }
  48. // single 上传单个文件; photo 为前端上传文件的input标签的name值
  49. // upload.single('video')每次上传单个文件的配置信息
  50. web.post('/upload',upload.single('video'), function (req, res) {
  51. // res.send('')
  52. console.log('上传成功')
  53. })
  54. web.get('/video', function (req, res) {
  55. getJsonFiles("./public/video");
  56. res.send(pa);
  57. })

这里前台直接使用的是Vant框架中的文件上传组件,但是你需要注意的是需要将
let data = new FormData()
data.append('video', file.file)
然后再传到后台去

  1. <template>
  2. <div class="upload">
  3. <div class="back" @click="onClickLeft">
  4. <van-icon name="arrow-left" color="#00CED1" size="26" />
  5. </div>
  6. <div class="box">
  7. <van-uploader :after-read="afterRead" :max-count="1" :max-size="10485760" v-model="fileList" accept="video/*" @oversize='chance()' />
  8. <p>请上传不大于10M视频</p>
  9. </div>
  10. </div>
  11. </template>
  12. <script> export default { name: 'upload', data () { return { fileList: [], e: 'video' } }, methods: { chance () { this.$notify({ message: '文件大小过大,请上传小于10M视频', duration: 1000, background: '#FFA500' }) }, onClickLeft () { history.back() }, afterRead (file) { // console.log(file.content)// base64 // function dataURItoBlob (base64Data) { // var byteString // if (base64Data.split(',')[0].indexOf('base64') >= 0) byteString = atob(base64Data.split(',')[1]) // else byteString = unescape(base64Data.split(',')[1]) // var mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0] // var ia = new Uint8Array(byteString.length) // for (var i = 0; i < byteString.length; i++) { // ia[i] = byteString.charCodeAt(i) // } // return new Blob([ia], { // type: mimeString // }) // } // console.log(dataURItoBlob(file.content)) let data = new FormData() data.append('video', file.file) // 此时可以自行将文件上传至服务器 this.$axios({ url: 'https://xxx/xxx/upload/', method: 'POST', headers: { 'Content-Type': 'multipart/form-data' }, data: data }).then((response) => { // success }) .catch((error) => { // error console.log(error) }) // console.log(file) this.$notify({ message: '发布成功', duration: 1000, background: '#07C160' }) } }, mounted () { this.$axios({ url: 'https://xxx/xxx/username/', method: 'POST', data: { name: this.$route.params.name } }).then((response) => { // success console.log(response) }) .catch((error) => { // error console.log(error) }) } } </script>

发表评论

表情:
评论列表 (有 0 条评论,417人围观)

还没有评论,来说两句吧...

相关阅读

    相关 最近关注的项目

    最近使用到的相关的技术 1、性能测试: 基准性能测试:sysbench 性能测试工具: jmeter 分布式服务跟踪:Dapper 2、单元测试: testng 3

    相关 项目集成总结

            短信接口         项目需要集成短信功能。网上查了很多资料,了解到有下面几种短信途径。           1.      可以通过移动等运营商