zoukankan      html  css  js  c++  java
  • 「小程序JAVA实战」小程序上传短视频(46)

    转自:https://idig8.com/2018/09/14/xiaochengxujavashizhanxiaochengxushangchuanduanshipin45/

    个人信息:用户上传短视频。

    业务流程

    1. 用户选择视频(10秒限制),也可以通过摄像头拍摄
    2. 打开选择背景音乐。
    3. 可以选择音乐或者不选择输入视频的描述。
    4. controller 上传视频
    5. 保存视频的截图
    6. 用户是否选择背景音乐
      7.1 是:直接保存视频
      7.2 否:合并视频和背景音乐,保存视频

    微信插件

    官方介绍:https://developers.weixin.qq.com/miniprogram/dev/api/media-video.html#wxchoosevideoobject

    • 代码修改
      > 可以获取到通过微信的组件获取到视频的长度,宽度,高度,视频的截图,视频的临时路径,时长。然后针对这些可以判断出来是否允许上传。
    // pages/mine/mine.js
    const app = getApp()
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        faceImage: "../../resource/images/noneface.png",
        nickname: "昵称",
        fansCounts: 0,
        followCounts: 0,
        receiveLikeCounts: 0,
      },
      /**
       * 用户注销
       */
      logout:function(e){
        var user = app.userInfo;
        wx.showLoading({
          title: '正在注销中。。。'
        });
        wx.request({
          url: app.serverUrl + "/logout?userId="+user.id,
          method: "POST",
          header: {
            'content-type': 'application/json' // 默认值
          },
          success: function (res) {
            console.log(res.data);
            var status = res.data.status;
            wx.hideLoading();
            if (status == 200) {
              wx.showToast({
                title: "用户注销成功~!",
                icon: 'none',
                duration: 3000
              })
              app.userInfo = null;
              wx.redirectTo({
                url: '../userRegister/userRegister',
              })
    
            } else if (status == 500) {
              wx.showToast({
                title: res.data.msg,
                icon: 'none',
                duration: 3000
              })
            }
          }
        })
      },
      /**
       * 头像上传
       */
      uploadFace:function(e){
        var user = app.userInfo;
        var me = this;
        wx.chooseImage({
          count: 1, // 默认9
          sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
          sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
          success: function (res) {
            // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
            var tempFilePaths = res.tempFilePaths
            if (tempFilePaths.length>0){
              console.log(tempFilePaths[0]);
                  wx.uploadFile({
                    url: app.serverUrl + "/user/uploadFace?userId=" + user.id, //仅为示例,非真实的接口地址
                    filePath: tempFilePaths[0],
                    name: 'file',
                    success: function (res) {
                      var data = JSON.parse(res.data);
                      console.log(data);
                       wx.hideLoading();
                      if (data.status == 200) {
                        wx.showToast({
                          title: "用户上传成功~!",
                          icon: 'none',
                          duration: 3000
                        })
                        me.setData({
                          faceUrl: app.serverUrl+data.data
                        })
    
    
                      } else if (data.status == 500) {
                        wx.showToast({
                          title: data.msg,
                          icon: 'none',
                          duration: 3000
                        })
                      }
                    }
                  })
            }
    
          }
        })
      },
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function (options) {
        var me = this;
        wx.showLoading({
          title: '正在获取用户信息。。。'
        });
        wx.request({
          url: app.serverUrl + "/user/queryByUserId?userId=" + app.userInfo.id,
          method: "POST",
          header: {
            'content-type': 'application/json' // 默认值
          },
          success: function (res) {
            console.log(res.data);
            var status = res.data.status;
            var userInfo = res.data.data;
            wx.hideLoading();
            var faceImage = me.data.faceUrl;
            if (userInfo.faceImage != null && userInfo.faceImage != '' && userInfo.faceImage!=undefined){
              faceImage = app.serverUrl +userInfo.faceImage;
            }
            me.setData({
              faceImage: faceImage,
              fansCounts: userInfo.fansCounts,
              followCounts: userInfo.followCounts,
              receiveLikeCounts: userInfo.receiveLikeCounts,
              nickname: userInfo.nickname
            })
          }
        })
      },
    
      uploadVideo:function(e){
        var me = this
        wx.chooseVideo({
          sourceType: ['album', 'camera'],
          success: function (res) {
            console.log(res);
            var tempDuration = res.duration;
            var tempHeight = res.height;
            var tempWidth = res.width;
            var tempSize = res.size;
            var tempFilePath = res.tempFilePath;
            var tempFilePath = res.thumbTempFilePath;
            if (tempDuration>20){
              wx.showToast({
                title: "视频太长了老铁不稳~",
                icon: 'none',
                duration: 3000
              })
            } else if (tempDuration <5){
              wx.showToast({
                title: "视频太短了不到5秒。老铁不稳~",
                icon: 'none',
                duration: 3000
              })
            } else{
              //进行上传
            }
          }
        })
      },
    
      /**
       * 生命周期函数--监听页面初次渲染完成
       */
      onReady: function () {
    
      },
    
      /**
       * 生命周期函数--监听页面显示
       */
      onShow: function () {
    
      },
    
      /**
       * 生命周期函数--监听页面隐藏
       */
      onHide: function () {
    
      },
    
      /**
       * 生命周期函数--监听页面卸载
       */
      onUnload: function () {
    
      },
    
      /**
       * 页面相关事件处理函数--监听用户下拉动作
       */
      onPullDownRefresh: function () {
    
      },
    
      /**
       * 页面上拉触底事件的处理函数
       */
      onReachBottom: function () {
    
      },
    
      /**
       * 用户点击右上角分享
       */
      onShareAppMessage: function () {
    
      }
    })
    
    • 增加选择背景音乐的界面
      >用户可以选择视频,接下来我们选择北京音乐的界面。用户选择音乐,或者用户可以不选择音乐直接提交不选择音乐直接提交。官方界面:https://developers.weixin.qq.com/miniprogram/dev/component/audio.html

    • 新建页面
      “` mine.js
      // pages/mine/mine.js
      const app = getApp()
      Page({

      /**

      • 页面的初始数据
        */
        data: {
        faceImage: “../../resource/images/noneface.png”,
        nickname: “昵称”,
        fansCounts: 0,
        followCounts: 0,
        receiveLikeCounts: 0,
        },
        /**
      • 用户注销
        */
        logout:function(e){
        var user = app.userInfo;
        wx.showLoading({
        title: ‘正在注销中。。。’
        });
        wx.request({
        url: app.serverUrl + “/logout?userId=”+user.id,
        method: “POST”,
        header: {
        ‘content-type’: ‘application/json’ // 默认值
        },
        success: function (res) {
        console.log(res.data);
        var status = res.data.status;
        wx.hideLoading();
        if (status == 200) {
        wx.showToast({
        title: “用户注销成功~!”,
        icon: ‘none’,
        duration: 3000
        })
        app.userInfo = null;
        wx.redirectTo({
        url: ‘../userRegister/userRegister’,
        })

        } else if (status == 500) {
        wx.showToast({
        title: res.data.msg,
        icon: ‘none’,
        duration: 3000
        })
        }
        }
        })
        },
        /**

      • 头像上传
        */
        uploadFace:function(e){
        var user = app.userInfo;
        var me = this;
        wx.chooseImage({
        count: 1, // 默认9
        sizeType: [‘compressed’], // 可以指定是原图还是压缩图,默认二者都有
        sourceType: [‘album’, ‘camera’], // 可以指定来源是相册还是相机,默认二者都有
        success: function (res) {
        // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
        var tempFilePaths = res.tempFilePaths
        if (tempFilePaths.length>0){
        console.log(tempFilePaths[0]);
        wx.uploadFile({
        url: app.serverUrl + “/user/uploadFace?userId=” + user.id, //仅为示例,非真实的接口地址
        filePath: tempFilePaths[0],
        name: ‘file’,
        success: function (res) {
        var data = JSON.parse(res.data);
        console.log(data);
        wx.hideLoading();
        if (data.status == 200) {
        wx.showToast({
        title: “用户上传成功~!”,
        icon: ‘none’,
        duration: 3000
        })
        me.setData({
        faceUrl: app.serverUrl+data.data
        })

              } else if (data.status == 500) {
                wx.showToast({
                  title: data.msg,
                  icon: 'none',
                  duration: 3000
                })
              }
            }
          })
        

        }

        }
        })
        },
        /**

      • 生命周期函数–监听页面加载
        */
        onLoad: function (options) {
        var me = this;
        wx.showLoading({
        title: ‘正在获取用户信息。。。’
        });
        wx.request({
        url: app.serverUrl + “/user/queryByUserId?userId=” + app.userInfo.id,
        method: “POST”,
        header: {
        ‘content-type’: ‘application/json’ // 默认值
        },
        success: function (res) {
        console.log(res.data);
        var status = res.data.status;
        var userInfo = res.data.data;
        wx.hideLoading();
        var faceImage = me.data.faceUrl;
        if (userInfo.faceImage != null && userInfo.faceImage != ” && userInfo.faceImage!=undefined){
        faceImage = app.serverUrl +userInfo.faceImage;
        }
        me.setData({
        faceImage: faceImage,
        fansCounts: userInfo.fansCounts,
        followCounts: userInfo.followCounts,
        receiveLikeCounts: userInfo.receiveLikeCounts,
        nickname: userInfo.nickname
        })
        }
        })
        },

      uploadVideo:function(e){
      var me = this
      wx.chooseVideo({
      sourceType: [‘album’, ‘camera’],
      success: function (res) {
      console.log(res);
      var tempDuration = res.duration;
      var tempHeight = res.height;
      var tempWidth = res.width;
      var tempSize = res.size;
      var tempFilePath = res.tempFilePath;
      var thumbTempFilePath = res.thumbTempFilePath;
      if (tempDuration>20){
      wx.showToast({
      title: “视频太长了老铁不稳~”,
      icon: ‘none’,
      duration: 3000
      })
      } else if (tempDuration <5){
      wx.showToast({
      title: “视频太短了不到5秒。老铁不稳~”,
      icon: ‘none’,
      duration: 3000
      })
      } else{
      wx.navigateTo({
      url: ‘../chooseBgm/chooseBgm?tempDuration=’ + tempDuration
      + ‘&tempHeight=’ + tempHeight
      + ‘&tempWidth=’ + tempWidth
      + ‘&tempSize=’ + tempSize
      + ‘&tempFilePath=’ + tempFilePath
      + ‘&thumbTempFilePath=’ + thumbTempFilePath
      })
      }
      }
      })
      },

      /**

      • 生命周期函数–监听页面初次渲染完成
        */
        onReady: function () {

      },

      /**

      • 生命周期函数–监听页面显示
        */
        onShow: function () {

      },

      /**

      • 生命周期函数–监听页面隐藏
        */
        onHide: function () {

      },

      /**

      • 生命周期函数–监听页面卸载
        */
        onUnload: function () {

      },

      /**

      • 页面相关事件处理函数–监听用户下拉动作
        */
        onPullDownRefresh: function () {

      },

      /**

      • 页面上拉触底事件的处理函数
        */
        onReachBottom: function () {

      },

      /**

      • 用户点击右上角分享
        */
        onShareAppMessage: function () {

      }
      })





    ** chooseBgm.wxml <view> <form bindsubmit='upload'> <radio-group name="bgmId"> <block wx:for="{{bgmList}}"> <view class='container'> <audio name="{{item.name}}" author="{{item.author}}" src="{{serverUrl}}{{item.path}}" style='300px' id="myAudio" controls loop></audio> <radio style='margin-top:20px;' value='{{item.id}}'></radio> </view> </block> </radio-group> <view class="inputView"> <label class="loginLabel">视频描述:</label> <input name="desc" class="inputText" placeholder="说点什么吧" /> </view> <!-- 提交 --> <button class="submitBtn" type="primary" form-type='submit'>上传视频</button> <button class="gobackBtn" type="warn" form-type='reset'>重置</button> </form> </view>

    chooseBgm.js

    const app = getApp()
    
    Page({
        data: {
          poster: 'http://y.gtimg.cn/music/photo_new/T002R300x300M000003rsKF44GyaSk.jpg?max_age=2592000',
          name: '此时此刻',
          author: '许巍',
          src: 'http://ws.stream.qqmusic.qq.com/M500001VfvsJ21xFqb.mp3?guid=ffffffff82def4af4b12b3cd9337d5e7&uin=346897220&vkey=6292F51E1E384E06DCBDC9AB7C49FD713D632D313AC4858BACB8DDD29067D3C601481D36E62053BF8DFEAF74C0A5CCFADD6471160CAF3E6A&fromtag=46',
          serverUrl:"",
          videoParams:{}
        },
        onLoad:function(params){
          var me = this;
          console.log(params);
    
          me.setData({
            videoParams:params
          })
    
          wx.showLoading({
            title: '请等待...',
          });
          var serverUrl = app.serverUrl;
          // 调用后端
          wx.request({
            url: serverUrl + '/bgm/list',
            method: "POST",
            header: {
              'content-type': 'application/json', // 默认值
            },
            success: function (res) {
              console.log(res.data);
              wx.hideLoading();
              if (res.data.status == 200) {
                var bgmList = res.data.data;
                me.setData({
                  bgmList: bgmList,
                  serverUrl: serverUrl
                });
              } else if (res.data.status == 502) {
                wx.showToast({
                  title: res.data.msg,
                  duration: 2000,
                  icon: "none",
                  success: function () {
                    wx.redirectTo({
                      url: '../userLogin/login',
                    })
                  }
                });
              }
            }
          })
        },
      upload:function(e){
        var me = this;
        var datasParams = me.data.videoParams;
        var bgmId = e.detail.value.bgmId;
        var desc = e.detail.value.desc;
        console.log("bgmId:"+bgmId);
        console.log("desc:" + desc);
        var tempDuration = datasParams.tempDuration;
        var tempHeight = datasParams.tempHeight;
        var tempWidth = datasParams.tempWidth;
        var tempSize = datasParams.tempSize;
        var tempFilePath = datasParams.tempFilePath;
        var thumbTempFilePath = datasParams.thumbTempFilePath;
        var userId = app.userInfo.id;
    
    
        debugger;
        wx.showLoading({
          title: '请等待...',
        });
        var serverUrl = app.serverUrl;
        // 调用后端
       wx.uploadFile({
         url: serverUrl + '/video/upload',
         filePath: tempFilePath,
         formData:{
           userId: userId,
           bgmId: bgmId,
           videoSeconds: tempDuration,
           videoWidth: tempWidth,
           videoHeight: tempHeight,
           desc: desc,
         },
         name: 'file',
         success:function(res){
          console.log(res);
           wx.hideLoading();
         }
    
       })
      }
    })
    
    
    

    后端开发

    后端接口在一个服务器上,后端的web在一台服务器上。后端的web上传小程序,需要同步到后端接口所在的一个服务器上。我们选择zokeeper。后边会讲

    • service中添加

    BgmService.java


    package com.idig8.service; import java.util.List; import com.idig8.pojo.Bgm; public interface BgmService { /** * 获取所有的Bgm列表 * @return */ public List<Bgm> queryBgmList(); }

    BgmServiceImpl.java

    package com.idig8.service.Impl;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Propagation;
    import org.springframework.transaction.annotation.Transactional;
    
    import com.idig8.mapper.BgmMapper;
    import com.idig8.pojo.Bgm;
    import com.idig8.service.BgmService;
    
    @Service
    public class BgmServiceImpl implements BgmService {
    
        @Autowired
        private BgmMapper bgmMapper;
    
    
        @Transactional(propagation =Propagation.SUPPORTS)
        @Override
        public List<Bgm> queryBgmList(){
    
            return bgmMapper.selectAll();
        }
    
    }
    
    

    BgmController.java

    package com.idig8.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.idig8.service.BgmService;
    import com.idig8.utils.JSONResult;
    
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    
    @RestController
    @Api(value="背景音乐接口",tags={"背景音乐接口的controller"})
    @RequestMapping(value = "/bgm")
    public class BgmController extends BasicController{
    
        @Autowired
        private BgmService bgmService;
    
    
    
        @ApiOperation(value="获取所有背景音乐",notes="通过获取所有背景音乐")
        @PostMapping("/list")
        public JSONResult list() {
            return JSONResult.ok(bgmService.queryBgmList());
        }
    
    
    }
    
    

    接口已经在swagger验证通过。

    小程序开发环境中会报net::ERR_INSUFFICIENT_RESOURCES这个错误,在真机中,不会出现该错误,忽略即可。

    PS:通过个人页面传递视频信息,到开发新界面背景音乐和描述,最后到文件信息上传到后台功能已经开发完毕。

  • 相关阅读:
    leetcode443
    leetcode429
    leetcode55
    2019-8-31-PowerShell-拿到最近的10个系统日志
    2019-6-11-WPF-如何在应用程序调试启动
    2019-8-31-C#-将-Begin-和-End-异步方法转-task-异步
    2019-9-18-WPF-笔刷绑定不上可能的原因
    2019-3-25-win10-uwp-如何将像素数组转-png-文件
    2018-9-30-C#-从零开始写-SharpDx-应用-画三角
    2018-8-10-Roslyn-节点的-Span-和--FullSpan-有什么区别
  • 原文地址:https://www.cnblogs.com/sharpest/p/10304786.html
Copyright © 2011-2022 走看看