zoukankan      html  css  js  c++  java
  • 微信小程序_(校园视)开发视频的展示页_上

      

      

      微信小程序_(校园视)  开发用户注册登陆  传送门 

      微信小程序_(校园视)  开发上传视频业务  传送门 

      微信小程序_(校园视)  开发视频的展示页-上  传送门 

      微信小程序_(校园视)  开发视频的展示页-下  传送门 

    小程序首页视频列表开发

      校园视小程序首页index将分别展示用户视频、用户头像、用户名字

    const app = getApp()
    
    Page({
      data: {
        // 用于分页的属性
        screenWidth: 350
      },
    
      onLoad: function (params) {
        var me = this;
        var screenWidth = wx.getSystemInfoSync().screenWidth;
    
        me.setData({
          screenWidth: screenWidth,
        });
      }
    })
    index.js
      <!-- <view wx:for="{{videoList}}" class="item-container">   -->
    
    
    
         <view style='{{screenWidth}}px;height:210px;' class='back-img'> 
            <image src="http://localhost:8081/190502AYNKPFRDD4/video/wx70d559ac5d37dd78.o6zAJs59F12Wz0jOMOX2L2uFIE_w.9StRAIr1vMWvc4e5d48a6fc4fabc84946439cb0983d0.jpg" style='{{screenWidth}}px;height:210px;' mode="aspectFit" bindtap='showVideoInfo' data-arrindex='{{index}}'></image>
         </view> 
    
    
        <view class="desc">
            <view class="faceName">
                <image class='myface' src="http://localhost:8081/190502AYNKPFRDD4/face/wx70d559ac5d37dd78.o6zAJs59F12Wz0jOMOX2L2uFIE_w.9WbWU2SnvtxFf1492da78d683e04183d3f63cc46dde9.png"></image>
                <view class="nickname">Gary</view>
            </view>
        </view>
    
    
      <!-- </view>   -->
    index.wxml
    .item-container {
        position: relative;
    }
    
    .cover {
        width: 100%;
        height: 400rpx;
        display: block; 
    }
    
    .back-img{
        display: block; 
        background-color: black;
    }
    
    .desc {
        margin-top: -40rpx;
        margin-bottom: 10rpx;
        display: flex;
        align-items: center;
    }
    
    .desc .right {
        display: flex;
        flex-direction: column;
        align-items: center;
    }
    
    .desc .faceName {
        display: flex;
        flex-direction: column;
        align-items: center;
        
        margin-left: 10px;
    }
    
    .title {
        font-size: 30rpx;
        margin-top: 10rpx;
        margin-left: 20rpx;
        width: 600rpx;
    }
    
    .myface {
        display: block;
        width: 60rpx;
        height: 60rpx;
        border-radius: 30rpx;
        margin-top: 10rpx;
        margin-right: 20rpx;
    }
    
    .nickname {
        font-size: 20rpx;
        margin-top: 6rpx;
        margin-right: 20rpx;
        color: darkgray;
    }
    index.wxss

    编写自定义mapper

       添加VideosVO.java实体层

    package com.imooc.pojp.vo;
    
    import java.util.Date;
    import javax.persistence.*;
    
    public class VideosVO {
    
        private String id;
        private String userId;
        private String audioId;
        private String videoDesc;
        private String videoPath;
        private Float videoSeconds;
        private Integer videoWidth;
        private Integer videoHeight;
        private String coverPath;
        private Long likeCounts;
        private Integer status;
        private Date createTime;
        private String faceImage;
        private String nickname;
        
        public String getFace_image() {
              return faceImage;
          }
    
          public void setFace_image(String faceImage) {
              this.faceImage = faceImage;
          }
    
          public String getNickname() {
              return nickname;
          }
    
          public void setNickname(String nickname) {
              this.nickname = nickname;
          }
    
        public String getId() {
            return id;
        }
    
        /**
         * @param id
         */
        public void setId(String id) {
            this.id = id;
        }
    
        /**
         * @return user_id
         */
        public String getUserId() {
            return userId;
        }
    
        /**
         * @param userId
         */
        public void setUserId(String userId) {
            this.userId = userId;
        }
    
        /**
         * @return audio_id
         */
        public String getAudioId() {
            return audioId;
        }
    
        /**
         * @param audioId
         */
        public void setAudioId(String audioId) {
            this.audioId = audioId;
        }
    
        /**
         * @return video_desc
         */
        public String getVideoDesc() {
            return videoDesc;
        }
    
        /**
         * @param videoDesc
         */
        public void setVideoDesc(String videoDesc) {
            this.videoDesc = videoDesc;
        }
    
        /**
         * @return video_path
         */
        public String getVideoPath() {
            return videoPath;
        }
    
        /**
         * @param videoPath
         */
        public void setVideoPath(String videoPath) {
            this.videoPath = videoPath;
        }
    
        /**
         * @return video_seconds
         */
        public Float getVideoSeconds() {
            return videoSeconds;
        }
    
        /**
         * @param videoSeconds
         */
        public void setVideoSeconds(Float videoSeconds) {
            this.videoSeconds = videoSeconds;
        }
    
        /**
         * @return video_width
         */
        public Integer getVideoWidth() {
            return videoWidth;
        }
    
        /**
         * @param videoWidth
         */
        public void setVideoWidth(Integer videoWidth) {
            this.videoWidth = videoWidth;
        }
    
        /**
         * @return video_height
         */
        public Integer getVideoHeight() {
            return videoHeight;
        }
    
        /**
         * @param videoHeight
         */
        public void setVideoHeight(Integer videoHeight) {
            this.videoHeight = videoHeight;
        }
    
        /**
         * @return cover_path
         */
        public String getCoverPath() {
            return coverPath;
        }
    
        /**
         * @param coverPath
         */
        public void setCoverPath(String coverPath) {
            this.coverPath = coverPath;
        }
    
        /**
         * @return like_counts
         */
        public Long getLikeCounts() {
            return likeCounts;
        }
    
        /**
         * @param likeCounts
         */
        public void setLikeCounts(Long likeCounts) {
            this.likeCounts = likeCounts;
        }
    
        /**
         * @return status
         */
        public Integer getStatus() {
            return status;
        }
    
        /**
         * @param status
         */
        public void setStatus(Integer status) {
            this.status = status;
        }
    
        /**
         * @return create_time
         */
        public Date getCreateTime() {
            return createTime;
        }
    
        /**
         * @param createTime
         */
        public void setCreateTime(Date createTime) {
            this.createTime = createTime;
        }
    }
    VideosVO.java

      在VideosMapperCustom.java层中添加数据库查询方法

    public interface VideosMapperCustom extends MyMapper<Videos> {
        
        public List<VideosVO> queryAllVideos();
        
    }
    package com.imooc.mapper;
    
    import java.util.List;
    
    import com.imooc.pojo.Videos;
    import com.imooc.pojp.vo.VideosVO;
    import com.imooc.utils.MyMapper;
    
    public interface VideosMapperCustom extends MyMapper<Videos> {
        
        public List<VideosVO> queryAllVideos();
        
    }
    VideosMapperCustom.java

      在VideosMapperCustom.xml中添加映射以及数据库查询语句

    <resultMap id="BaseResultMap" type="com.imooc.pojo.vo.VideosVO" >
        <!--
          WARNING - @mbg.generated
        -->
        <id column="id" property="id" jdbcType="VARCHAR" />
        <result column="user_id" property="userId" jdbcType="VARCHAR" />
        <result column="audio_id" property="audioId" jdbcType="VARCHAR" />
        <result column="video_desc" property="videoDesc" jdbcType="VARCHAR" />
        <result column="video_path" property="videoPath" jdbcType="VARCHAR" />
        <result column="video_seconds" property="videoSeconds" jdbcType="REAL" />
        <result column="video_width" property="videoWidth" jdbcType="INTEGER" />
        <result column="video_height" property="videoHeight" jdbcType="INTEGER" />
        <result column="cover_path" property="coverPath" jdbcType="VARCHAR" />
        <result column="like_counts" property="likeCounts" jdbcType="BIGINT" />
        <result column="status" property="status" jdbcType="INTEGER" />
        <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
        
        <result column="face_image" property="faceImage" jdbcType="VARCHAR" />
        <result column="nickname" property="nickname" jdbcType="VARCHAR" />  
      </resultMap>
      <select id="queryAllVideos" resultMap="BaseResultMap">
      
          select v.*,u.face_image as face_image,u.nickname as nickname from videos v
          left join users u on u.id = v.user_id
          where
              1 =1
              and v.status = 1
          order by v.create_time desc
      
      </select>

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
    <mapper namespace="com.imooc.mapper.VideosMapperCustom" >
      <resultMap id="BaseResultMap" type="com.imooc.pojo.vo.VideosVO" >
        <!--
          WARNING - @mbg.generated
        -->
        <id column="id" property="id" jdbcType="VARCHAR" />
        <result column="user_id" property="userId" jdbcType="VARCHAR" />
        <result column="audio_id" property="audioId" jdbcType="VARCHAR" />
        <result column="video_desc" property="videoDesc" jdbcType="VARCHAR" />
        <result column="video_path" property="videoPath" jdbcType="VARCHAR" />
        <result column="video_seconds" property="videoSeconds" jdbcType="REAL" />
        <result column="video_width" property="videoWidth" jdbcType="INTEGER" />
        <result column="video_height" property="videoHeight" jdbcType="INTEGER" />
        <result column="cover_path" property="coverPath" jdbcType="VARCHAR" />
        <result column="like_counts" property="likeCounts" jdbcType="BIGINT" />
        <result column="status" property="status" jdbcType="INTEGER" />
        <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
        
        <result column="face_image" property="faceImage" jdbcType="VARCHAR" />
        <result column="nickname" property="nickname" jdbcType="VARCHAR" />  
      </resultMap>
      
      <select id="queryAllVideos" resultMap="BaseResultMap">
      
          select v.*,u.face_image as face_image,u.nickname as nickname from videos v
          left join users u on u.id = v.user_id
          where
              1 =1
              and v.status = 1
          order by v.create_time desc
      
      </select>
      
    </mapper>
    VideosMapperCustom.xml

    视频列表分页查询接口

       Pagehelper做视频的分页

    package com.imooc.utils;
    
    import java.util.List;
    
    /**
     * @Description: 封装分页后的数据格式
     */
    public class PagedResult {
        
        private int page;            // 当前页数
        private int total;            // 总页数    
        private long records;        // 总记录数
        private List<?> rows;        // 每行显示的内容
        
        public int getPage() {
            return page;
        }
        public void setPage(int page) {
            this.page = page;
        }
        public int getTotal() {
            return total;
        }
        public void setTotal(int total) {
            this.total = total;
        }
        public long getRecords() {
            return records;
        }
        public void setRecords(long records) {
            this.records = records;
        }
        public List<?> getRows() {
            return rows;
        }
        public void setRows(List<?> rows) {
            this.rows = rows;
        }
    
    }
    PagedResult.java

      查询视频的VideoServiceImpl.java中getAllVideos(Integer page, Integer pageSize)方法

    @Override
        public PagedResult getAllVideos(Integer page, Integer pageSize) {
            
            PageHelper.startPage(page,pageSize);
            List<VideosVO> list= videosMapperCustom.queryAllVideos();
            
            PageInfo<VideosVO> pageList = new PageInfo<>(list);
            
            PagedResult pagedResult = new PagedResult();
            pagedResult.setPage(page);
            pagedResult.setTotal(pageList.getPages());
            pagedResult.setRows(list);
            pagedResult.setRecords(pageList.getTotal());
            
            
            return pagedResult;
        }

      在VideoController.java中添加查询视频的方法

    @PostMapping(value="/showAll")
        public IMoocJSONResult showAll(Integer page) throws Exception {
            
            if(page == null) {
                page = 1;
            }
            
            
            PagedResult result = videoService.getAllVideos(page,PAGE_SIZE);
            return IMoocJSONResult.ok(result);
            
        }
    package com.imooc.server.impl;
    
    import java.util.List;
    
    import org.n3r.idworker.Sid;
    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.github.pagehelper.PageHelper;
    import com.github.pagehelper.PageInfo;
    import com.imooc.mapper.BgmMapper;
    import com.imooc.mapper.UsersMapper;
    import com.imooc.mapper.VideosMapper;
    import com.imooc.mapper.VideosMapperCustom;
    import com.imooc.pojo.Bgm;
    import com.imooc.pojo.Users;
    import com.imooc.pojo.Videos;
    import com.imooc.pojp.vo.VideosVO;
    import com.imooc.service.BgmService;
    import com.imooc.service.UserService;
    import com.imooc.service.VideoService;
    import com.imooc.utils.PagedResult;
    
    import tk.mybatis.mapper.entity.Example;
    import tk.mybatis.mapper.entity.Example.Criteria;
    
    @Service
    public class VideoServiceImpl implements VideoService {
    
        @Autowired
        private VideosMapper videosMapper;
        
        @Autowired
        private VideosMapperCustom  videosMapperCustom;
        
        @Autowired
        private Sid sid;
        
    
        @Transactional(propagation = Propagation.REQUIRED)
        @Override
        public String saveVideo(Videos video) {
            
            String id = sid.nextShort();
            video.setId(id);
            
            videosMapper.insertSelective(video);
            
            return id;
        }
    
        @Transactional(propagation = Propagation.REQUIRED)
        @Override
        public void updateVideo(String videoId, String coverPath) {
            
            Videos video = new Videos();
            video.setId(videoId);
            video.setCoverPath(coverPath);
            videosMapper.updateByPrimaryKeySelective(video);
            
        }
    
        @Override
        public PagedResult getAllVideos(Integer page, Integer pageSize) {
            
            PageHelper.startPage(page,pageSize);
            List<VideosVO> list= videosMapperCustom.queryAllVideos();
            
            PageInfo<VideosVO> pageList = new PageInfo<>(list);
            
            PagedResult pagedResult = new PagedResult();
            pagedResult.setPage(page);
            pagedResult.setTotal(pageList.getPages());
            pagedResult.setRows(list);
            pagedResult.setRecords(pageList.getTotal());
            
            
            return pagedResult;
        }
    
    
        
    }
    VideoServiceImpl.java
    package com.imooc.controller;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.util.Date;
    import java.util.UUID;
    
    import org.apache.commons.lang3.StringUtils;
    import org.apache.tomcat.util.http.fileupload.IOUtils;
    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.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    import com.imooc.enums.VideoStatusEnum;
    import com.imooc.pojo.Bgm;
    import com.imooc.pojo.Users;
    import com.imooc.pojo.Videos;
    import com.imooc.service.BgmService;
    import com.imooc.service.VideoService;
    import com.imooc.utils.FetchVideoCover;
    import com.imooc.utils.IMoocJSONResult;
    import com.imooc.utils.MergeVideoMp3;
    import com.imooc.utils.PagedResult;
    
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiImplicitParam;
    import io.swagger.annotations.ApiImplicitParams;
    import io.swagger.annotations.ApiOperation;
    import io.swagger.annotations.ApiParam;
    
    
    @RestController
    @Api(value="视频相关业务的接口",tags= {"视频相关业务的controller"})
    @RequestMapping("/video")
    public class VideoController extends BasicController{
        
        @Autowired
        private BgmService bgmService;
        
        @Autowired
        private VideoService videoService;
        
        
        @ApiOperation(value="上传视频", notes="上传视频的接口")
        @ApiImplicitParams({
            @ApiImplicitParam(name="userId",value="用户id",required=true,
                    dataType="String" ,paramType="form"),
            @ApiImplicitParam(name="bgmId",value="背景音乐id",required=false,
                    dataType="String" ,paramType="form"),
            @ApiImplicitParam(name="videoSeconds",value="背景音乐播放长度",required=true,
                    dataType="String" ,paramType="form"),
            @ApiImplicitParam(name="videoWidth",value="视频的宽度",required=true,
                    dataType="String" ,paramType="form"),
            @ApiImplicitParam(name="videoHeight",value="视频的高度",required=true,
                    dataType="String" ,paramType="form"),
            @ApiImplicitParam(name="desc",value="视频的描述",required=false,
                    dataType="String" ,paramType="form")
        })
        @PostMapping(value="/upload",headers="content-type=multipart/form-data")
        public IMoocJSONResult uploadFace(String userId,
                String bgmId,double videoSeconds,int videoWidth,int videoHeight,String desc,
                @ApiParam(value="短视频",required=true)
                MultipartFile file) throws Exception {
            
                if(StringUtils.isBlank(userId)) {
                    return IMoocJSONResult.errorMsg("用户id不能为空...");
                }
            
                //文件保存命名空间
                //String fileSpace = "F:/imooc-video-gary";
                //保存到数据库中的相对路径
                String uploadPathDB = "/" + userId + "/video";
                String coverPathDB = "/" + userId + "/video";
                
                FileOutputStream fileOutputStream = null;
                InputStream inputStream = null;
                String finalVideoPath = "";
                try {
                    if( file != null ) {
    
                        String fileName = file.getOriginalFilename();
                        //Gary.mp4  使用spilt进行分割
                        String fileNamePrefix = fileName.split("\.")[0];
                        
                        
                        
                        if(StringUtils.isNoneBlank(fileName)) {
                            //文件上传的最终保存路径
                            
                            finalVideoPath = FILE_SPACE + uploadPathDB + "/" + fileName;
                            //设置数据库保存的路径
                            uploadPathDB += ("/" + fileName);
                            coverPathDB = coverPathDB + "/" + fileNamePrefix + ".jpg";
                            
                            File outFile = new File(finalVideoPath);
                            if(outFile.getParentFile()!=null || !outFile.getParentFile().isDirectory()) {
                                //创建父文件夹
                                outFile.getParentFile().mkdirs();
                            }
                            
                            fileOutputStream = new FileOutputStream(outFile);
                            inputStream = file.getInputStream();
                            IOUtils.copy(inputStream, fileOutputStream);
                        }
                        
                    }else {
                        return IMoocJSONResult.errorMsg("上传出错...");
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    return IMoocJSONResult.errorMsg("上传出错...");
                }finally {
                    if(fileOutputStream != null) {
                        fileOutputStream.flush();
                        fileOutputStream.close();
                    }
                }
                
                //判断bgmId是否为空,
                //如果不为空,那就查询bgm的信息,并且合并视频生成新的视频
                
                if(StringUtils.isNotBlank(bgmId)) {
                    Bgm bgm = bgmService.queryBgmById(bgmId);
                    String mp3InputPath = FILE_SPACE + bgm.getPath();
                    //System.out.println("1:mp3InputPath + "+mp3InputPath);
                    MergeVideoMp3 tool = new MergeVideoMp3(FFMPEG_EXE);
                    String videoInputPath = finalVideoPath;
                    
                    String videdoOutputName = UUID.randomUUID().toString() + ".mp4";
                    uploadPathDB = "/" + userId + "/video" + "/" +videdoOutputName;
                    finalVideoPath = FILE_SPACE + uploadPathDB;
                    tool.convertor(videoInputPath, mp3InputPath, videoSeconds, finalVideoPath);
                    
                }
                
                //对视频封面进行截图
                FetchVideoCover videoInfo = new FetchVideoCover(FFMPEG_EXE);
                videoInfo.getCover(finalVideoPath,FILE_SPACE + coverPathDB);
                
                //保存视频信息到数据库
                Videos video = new Videos();
                video.setAudioId(bgmId);
                video.setUserId(userId);
                video.setVideoSeconds((float)videoSeconds);
                video.setVideoHeight(videoHeight);
                video.setVideoWidth(videoWidth);
                video.setVideoDesc(desc);
                video.setVideoPath(uploadPathDB);
                video.setCoverPath(coverPathDB);
                video.setStatus(VideoStatusEnum.SUCCESS.value);
                video.setCreateTime(new Date());
                
                String videoId = videoService.saveVideo(video);
                
                return IMoocJSONResult.ok(videoId);
        }
        
        @ApiOperation(value="上传封面", notes="上传封面的接口")
        @ApiImplicitParams({        
            @ApiImplicitParam(name="userId",value="用户id",required=true,
                    dataType="String" ,paramType="form"),
            @ApiImplicitParam(name="videoId",value="视频主键id",required=true,
                    dataType="String" ,paramType="form")
        })
        @PostMapping(value="/uploadCover",headers="content-type=multipart/form-data")
        public IMoocJSONResult uploadCover(String userId,String videoId, 
                @ApiParam(value="视频封面",required=true)
                MultipartFile file) throws Exception {
            
                if(StringUtils.isBlank(userId) ||StringUtils.isBlank(videoId) ) {
                    return IMoocJSONResult.errorMsg("视频主键id和用户id不能为空...");
                }
            
                //文件保存命名空间
                //String fileSpace = "F:/imooc-video-gary";
                //保存到数据库中的相对路径
                String uploadPathDB = "/" + userId + "/video";
                
                FileOutputStream fileOutputStream = null;
                InputStream inputStream = null;
                String finalCoverPath = "";
                try {
                    if( file != null ) {
    
                        
                        String fileName = file.getOriginalFilename();
                        if(StringUtils.isNoneBlank(fileName)) {
                            //文件上传的最终保存路径
                            
                            finalCoverPath = FILE_SPACE + uploadPathDB + "/" + fileName;
                            //设置数据库保存的路径
                            uploadPathDB += ("/" + fileName);
                            
                            File outFile = new File(finalCoverPath);
                            if(outFile.getParentFile()!=null || !outFile.getParentFile().isDirectory()) {
                                //创建父文件夹
                                outFile.getParentFile().mkdirs();
                            }
                            
                            fileOutputStream = new FileOutputStream(outFile);
                            inputStream = file.getInputStream();
                            IOUtils.copy(inputStream, fileOutputStream);
                        }
                        
                    }else {
                        return IMoocJSONResult.errorMsg("上传出错...");
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    return IMoocJSONResult.errorMsg("上传出错...");
                }finally {
                    if(fileOutputStream != null) {
                        fileOutputStream.flush();
                        fileOutputStream.close();
                    }
                }
                
                videoService.updateVideo(videoId, uploadPathDB);
                
                return IMoocJSONResult.ok();
        }
        
        
        
        
        @PostMapping(value="/showAll")
        public IMoocJSONResult showAll(Integer page) throws Exception {
            
            if(page == null) {
                page = 1;
            }
            
            
            PagedResult result = videoService.getAllVideos(page,PAGE_SIZE);
            return IMoocJSONResult.ok(result);
            
        }
        
        
    }
    VideoController.java

    小程序端口的联调

       通过小程序端拿到index页面中分页数目

    onLoad: function (params) {
        var me = this;
        var screenWidth = wx.getSystemInfoSync().screenWidth;
    
        me.setData({
          screenWidth: screenWidth,
        });
    
        //获取当前的分页数
        var page = me.data.page;
        var serverUrl = app.serverUrl;
        wx.showLoading({
          title: '请等待,加载中...',
        })
    
        wx.request({
          url:serverUrl+'/video/showAll?page='+page,
          method:"POST",
          success:function(res){
            wx.hideLoading();
    
            console.log(res.data);
    
          }
        })
      }

      

    const app = getApp()
    
    Page({
      data: {
        // 用于分页的属性
        totalPage:1,
        page:1,
        videoList:[],
        screenWidth: 350,
        //用于展示图片
        serverUrl:""
      },
    
      onLoad: function (params) {
        var me = this;
        var screenWidth = wx.getSystemInfoSync().screenWidth;
    
        me.setData({
          screenWidth: screenWidth,
        });
    
        //获取当前的分页数
        var page = me.data.page;
        var serverUrl = app.serverUrl;
        wx.showLoading({
          title: '请等待,加载中...',
        })
    
        wx.request({
          url:serverUrl+'/video/showAll?page='+page,
          method:"POST",
          success:function(res){
            wx.hideLoading();
    
            console.log(res.data);
    
          }
        })
      }
    })
    index.js

      前端微信小程序展示与后端接口的联调

      <view wx:for="{{videoList}}" wx:key="" class="item-container">  
    
    
    
         <view style='{{screenWidth}}px;height:210px;' class='back-img'> 
            <image src="{{serverUrl}}{{item.coverPath}}" style='{{screenWidth}}px;height:210px;' mode="aspectFit" bindtap='showVideoInfo' data-arrindex='{{index}}'></image>
         </view> 
    
    
        <view class="desc">
            <view class="faceName">
                <image class='myface' src="{{serverUrl}}{{item.face_image}}"></image>
                <view class="nickname">{{item.nickname}}</view>
            </view>
        </view>
    
    
      </view>  
      
    index.wxml
    const app = getApp()
    
    Page({
      data: {
        // 用于分页的属性
        totalPage:1,
        page:1,
        videoList:[],
        screenWidth: 350,
        //用于展示图片
        serverUrl:""
      },
    
      onLoad: function (params) {
        var me = this;
        var screenWidth = wx.getSystemInfoSync().screenWidth;
    
        me.setData({
          screenWidth: screenWidth,
        });
    
        //获取当前的分页数
        var page = me.data.page;
        var serverUrl = app.serverUrl;
        wx.showLoading({
          title: '请等待,加载中...',
        })
    
        wx.request({
          url:serverUrl+'/video/showAll?page='+page,
          method:"POST",
          success:function(res){
            wx.hideLoading();
    
            console.log(res.data);
            //判断当前页面page是否是第一页,如果是第一页,那么设置videoList为空
            if(page==1){
              me.setData({
                videoList: []
              });
            }
    
            var videoList = res.data.data.rows;
            var newVideoList = me.data.videoList;
    
            me.setData({
              videoList: newVideoList.concat(videoList),
              page:page,
              totalPage: res.data.data.total,
              serverUrl: serverUrl
            });
    
          }
        })
      }
    })
    index.js

    首页视频列表-上拉分页

      小程序使用上拉刷新方法onReachBottom()

      封装显示视频方法getAllVideoList()

     getAllVideoList:function(page){
        var serverUrl = app.serverUrl;
        wx.showLoading({
          title: '请等待,加载中...',
        })
    
        wx.request({
          url: serverUrl + '/video/showAll?page=' + page,
          method: "POST",
          success: function (res) {
            wx.hideLoading();
    
            console.log(res.data);
            //判断当前页面page是否是第一页,如果是第一页,那么设置videoList为空
            if (page == 1) {
              me.setData({
                videoList: []
              });
            }
    
            var videoList = res.data.data.rows;
            var newVideoList = me.data.videoList;
    
            me.setData({
              videoList: newVideoList.concat(videoList),
              page: page,
              totalPage: res.data.data.total,
              serverUrl: serverUrl
            });
    
          }
        })
      }

       实现上拉刷新,当刷新页数大于后台设置的5时候,会暂时数据库中后5个视频,直到将数据库中所有的视频都展示完全

      <view wx:for="{{videoList}}" wx:key="" class="item-container">  
    
    
    
         <view style='{{screenWidth}}px;height:210px;' class='back-img'> 
            <image src="{{serverUrl}}{{item.coverPath}}" style='{{screenWidth}}px;height:210px;' mode="aspectFit" bindtap='showVideoInfo' data-arrindex='{{index}}'></image>
         </view> 
    
    
        <view class="desc">
            <view class="faceName">
                <image class='myface' src="{{serverUrl}}{{item.face_image}}"></image>
                <view class="nickname">{{item.nickname}}</view>
            </view>
        </view>
    
    
      </view>  
      
    index.wxml
    const app = getApp()
    
    Page({
      data: {
        // 用于分页的属性
        totalPage:1,
        page:1,
        videoList:[],
        screenWidth: 350,
        //用于展示图片
        serverUrl:""
      },
    
      onLoad: function (params) {
        var me = this;
        var screenWidth = wx.getSystemInfoSync().screenWidth;
    
        me.setData({
          screenWidth: screenWidth,
        });
    
        //获取当前的分页数
        var page = me.data.page;
        me.getAllVideoList(page);
      },
    
      getAllVideoList:function(page){
        var me = this;
        var serverUrl = app.serverUrl;
        wx.showLoading({
          title: '请等待,加载中...',
        })
    
        wx.request({
          url: serverUrl + '/video/showAll?page=' + page,
          method: "POST",
          success: function (res) {
            wx.hideLoading();
    
            console.log(res.data);
            //判断当前页面page是否是第一页,如果是第一页,那么设置videoList为空
            if (page == 1) {
              me.setData({
                videoList: []
              });
            }
    
            var videoList = res.data.data.rows;
            var newVideoList = me.data.videoList;
    
            me.setData({
              videoList: newVideoList.concat(videoList),
              page: page,
              totalPage: res.data.data.total,
              serverUrl: serverUrl
            });
    
          }
        })
      },
    
      onReachBottom:function(){
        var me = this;
        var currentPage = me.data.page;
        var totalPage = me.data.totalPage;
    
        //判断当前页数和总页数是否相等,如果相等则不需要查询
        if (currentPage == totalPage){
          wx.showToast({
            title: '已经没有视频啦~~',
            icon:"none"
          })
          return ;
        }
    
        var page = currentPage + 1;
    
        me.getAllVideoList(page);
      }
    
    })
    index.js

    首页视频列表-下拉刷新

      微信小程序onPullDownRefresh页面相关事件处理函数--监听用户下拉动作,enablePullDownRefresh开启下拉刷新

      在index.json中开启下拉刷新熟悉

    {
      "enablePullDownRefresh":true,
      "backgroundTextStyle":"dark"
    }

      wx.showNavigationBarLoading()在当前页面显示导航条加载动画

    {
      "enablePullDownRefresh":true,
      "backgroundTextStyle":"dark"
    }
    index.json
      <view wx:for="{{videoList}}" wx:key="" class="item-container">  
    
    
    
         <view style='{{screenWidth}}px;height:210px;' class='back-img'> 
            <image src="{{serverUrl}}{{item.coverPath}}" style='{{screenWidth}}px;height:210px;' mode="aspectFit" bindtap='showVideoInfo' data-arrindex='{{index}}'></image>
         </view> 
    
    
        <view class="desc">
            <view class="faceName">
                <image class='myface' src="{{serverUrl}}{{item.face_image}}"></image>
                <view class="nickname">{{item.nickname}}</view>
            </view>
        </view>
    
    
      </view>  
      
    index.wxml
    const app = getApp()
    
    Page({
      data: {
        // 用于分页的属性
        totalPage:1,
        page:1,
        videoList:[],
        screenWidth: 350,
        //用于展示图片
        serverUrl:""
      },
    
      onLoad: function (params) {
        var me = this;
        var screenWidth = wx.getSystemInfoSync().screenWidth;
    
        me.setData({
          screenWidth: screenWidth,
        });
    
        //获取当前的分页数
        var page = me.data.page;
        me.getAllVideoList(page);
      },
    
      getAllVideoList:function(page){
        var me = this;
        var serverUrl = app.serverUrl;
        wx.showLoading({
          title: '请等待,加载中...',
        })
    
        wx.request({
          url: serverUrl + '/video/showAll?page=' + page,
          method: "POST",
          success: function (res) {
            wx.hideLoading();
            wx.hideNavigationBarLoading();
            //停止当前页面下拉刷新
            wx.stopPullDownRefresh();
    
            console.log(res.data);
            //判断当前页面page是否是第一页,如果是第一页,那么设置videoList为空
            if (page == 1) {
              me.setData({
                videoList: []
              });
            }
    
            var videoList = res.data.data.rows;
            var newVideoList = me.data.videoList;
    
            me.setData({
              videoList: newVideoList.concat(videoList),
              page: page,
              totalPage: res.data.data.total,
              serverUrl: serverUrl
            });
    
          }
        })
      },
    
      onPullDownRefresh:function(){
        wx.showNavigationBarLoading()
        this.getAllVideoList(1);
      },
    
      onReachBottom:function(){
        var me = this;
        var currentPage = me.data.page;
        var totalPage = me.data.totalPage;
    
        //判断当前页数和总页数是否相等,如果相等则不需要查询
        if (currentPage == totalPage){
          wx.showToast({
            title: '已经没有视频啦~~',
            icon:"none"
          })
          return ;
        }
    
        var page = currentPage + 1;
    
        me.getAllVideoList(page);
      }
    
    })
    index.js

    视频组件与api

      muted:设置video组件是否有声音

      initial-time:指定视频初始播放位置

      direction:设置全屏时视频的方向,不指定则根据宽高比自动判断

      controls:是否显示默认播放控件(播放/暂停按钮、播放进度、时间)

      duration:指定视频时长

      danmu-list:弹幕列表

      enable-danmu:是否展示弹幕,只在初始化时有效,不能动态变更

      danmu-btn:是否显示弹幕按钮,只在初始化时有效,不能动态变更

      autoplay:是否自动播放

      loop:是否循环播放

      page-gesture:在非全屏模式下,是否开启亮度与音量调节手势(废弃,见 vslide-gesture)

      direction:设置全屏时视频的方向,不指定则根据宽高比自动判断

    <video src="http://192.168.1.110:8081/190502H6YA6C4ZR4/video/feff1fba-0f73-43ea-ae3a-52dbd5343926.mp4"
    muted="{{true}}"
    initial-time="2"
    direction="3"
    controls="{{true}}"
    danmu-list="{{danmuList}}"
    enable-danmu="{{true}}"
    danmu-btn="{{true}}"
    autoplay="{{false}}"
    loop="{{true}}"
    page-gesture="{{true}}"
    direction="0"
    ></video>
    videotest.wxml
    const app = getApp()
    
    Page({
    
      data: {
        danmuList: [
          {
            text: '第 1s 出现的弹幕',
            color: '#ff0000',
            time: 1
          },
          {
            text: '第 3s 出现的弹幕',
            color: '#ff00ff',
            time: 3
          }]
      }
    
    })
    videotest.js

    视频展示页开发-视频展示页面

      开始视频的展示页面,将小视频的视频填充满整个页面 

    <view style='100%;height:100%;'>
    
    <video   src="http://192.168.1.110:8081/190502H6YA6C4ZR4/video/feff1fba-0f73-43ea-ae3a-52dbd5343926.mp4"
    muted="{{true}}"
    controls="{{false}}"
    
    autoplay="{{true}}"
    loop="{{true}}"
    
    enable-progress-gesture="{{false}}"
    style='100%;height:100%;'
    objectFit='{{cover}}'
    ></video>
    
    </view>
    videoinfo.wxml
    const app = getApp()
    
    Page({
      data: {
        cover:"cover"
      }
    
    })
    videoinfo.js

    视频展示页开发-图标放置

      cover-view组件:覆盖在文本之上的组件

      为方便展示效果,我换了一个视频作为展示

      上方上传视频、搜索按钮图标button的放置

    <cover-view class='container'>
                <!-- 上传视频 -->
    
                <cover-image src='../resource/images/camera.png' style='50rpx;height:50rpx;' bindtap='upload'></cover-image>
    
    
                <!-- 搜索按钮 -->
                <cover-image src='../resource/images/search.png' style='45rpx;height:45rpx;' bindtap='showSearch'></cover-image>
    
    </cover-view>

      左侧图标用户头像、喜欢收藏按钮、评论按钮、分享按钮的放置

    <cover-view class='container-me'>
                <!-- 头像 -->
                <cover-image class="face" src='{{publisher.faceImage}}' bindtap='showPublisher'></cover-image>
    
    
                <!-- 喜欢收藏按钮 -->
                <block wx:if="{{userLikeVideo}}">
                    <cover-image class="size-me" src='../resource/images/like.png' style='margin-top:30rpx;' bindtap='likeVideoOrNot'></cover-image>
                </block>
                <block wx:else>
                    <cover-image class="size-me" src='../resource/images/unlike.png' style='margin-top:30rpx;' bindtap='likeVideoOrNot'></cover-image>
                </block>
    
    
                <!-- 评论按钮 -->
                <cover-image class="size-me" src='../resource/images/comments.png' style='margin-top:30rpx;' bindtap='leaveComment'></cover-image>
    
                <!-- 分享按钮 -->
                <cover-image class="size-me" src='../resource/images/share.png' style='margin-top:30rpx;' bindtap='shareMe'></cover-image>
    
    </cover-view>

      下方首页按钮和我的按钮图标放置

    <cover-view class='container-bottom'>
                <!-- 首页按钮 -->
                <cover-image class='' src='../resource/images/index.png' class="size-bottom" bindtap='showIndex'></cover-image>
    
                <!-- 我的关注 -->
                <cover-image class='' src='../resource/images/follow.png' class="size-bottom" bindtap='showFollow'></cover-image>
    
                <!-- 我的按钮 -->
                <cover-image class='' src='../resource/images/mine.png' class="size-bottom" bindtap='showMine'></cover-image>
    
    </cover-view>

    <view style='100%;height:100%;'>
    
    <video   src="http://1257737090.vod2.myqcloud.com/d7d12d2bvodcq1257737090/f42e13285285890785678595639/rG447485Zc0A.mp4"
    muted="{{true}}"
    
    autoplay="{{true}}"
    loop="{{true}}"
    
    enable-progress-gesture="{{false}}"
    style='100%;height:100%;'
    objectFit='{{cover}}'
    >
    
    <cover-view class='container'>
                <!-- 上传视频 -->
    
                <cover-image src='../resource/images/camera.png' style='50rpx;height:50rpx;' bindtap='upload'></cover-image>
    
    
                <!-- 搜索按钮 -->
                <cover-image src='../resource/images/search.png' style='45rpx;height:45rpx;' bindtap='showSearch'></cover-image>
    
    </cover-view>
    
    <cover-view class='container-me'>
                <!-- 头像 -->
                <cover-image class="face" src='{{publisher.faceImage}}' bindtap='showPublisher'></cover-image>
    
    
                <!-- 喜欢收藏按钮 -->
                <block wx:if="{{userLikeVideo}}">
                    <cover-image class="size-me" src='../resource/images/like.png' style='margin-top:30rpx;' bindtap='likeVideoOrNot'></cover-image>
                </block>
                <block wx:else>
                    <cover-image class="size-me" src='../resource/images/unlike.png' style='margin-top:30rpx;' bindtap='likeVideoOrNot'></cover-image>
                </block>
    
    
                <!-- 评论按钮 -->
                <cover-image class="size-me" src='../resource/images/comments.png' style='margin-top:30rpx;' bindtap='leaveComment'></cover-image>
    
                <!-- 分享按钮 -->
                <cover-image class="size-me" src='../resource/images/share.png' style='margin-top:30rpx;' bindtap='shareMe'></cover-image>
    
    </cover-view>
    
     <cover-view class='container-words'>
    
                <cover-view>@{{publisher.nickname}}</cover-view>
    
                <cover-view class='video-desc'>{{videoInfo.videoDesc}}</cover-view>
    
    
    
    </cover-view>
    
    
    <cover-view class='container-bottom'>
                <!-- 首页按钮 -->
                <cover-image class='' src='../resource/images/index.png' class="size-bottom" bindtap='showIndex'></cover-image>
    
                <!-- 我的关注 -->
                <cover-image class='' src='../resource/images/follow.png' class="size-bottom" bindtap='showFollow'></cover-image>
    
                <!-- 我的按钮 -->
                <cover-image class='' src='../resource/images/mine.png' class="size-bottom" bindtap='showMine'></cover-image>
    
    </cover-view>
    
    
    </video>
    
    </view>
    videoinfo.wxml
    page {
        height: 100%;
        background-color: #141414;
    }
    
    .container {
        display: flex;
        margin-top: 20rpx;
        margin-left: 50rpx;
        margin-right: 50rpx;
        justify-content: space-between;
    }
    
    .container-me {
        margin-top: 360rpx;
        margin-left: 50rpx;
        width: 80rpx;
    }
    
    .container-words {
        /* display: flex;
        flex-direction: column; */
        margin-top: 60rpx;
        margin-left: 50rpx;
        width: 100%;
        color: white;
        font-size: 14px;
    }
    
    .inputText {
        background-color: gainsboro;
        height: 35px;
    }
    
    .video-desc {
        width: 600rpx;
        height: 100rpx;
        white-space: pre-wrap;
    }
    
    .container-bottom {
        /* bottom: 10px;  */
        display: flex;
        margin-top: 60rpx;
        margin-left: 50rpx;
        margin-right: 50rpx;
        /* margin-bottom: 10rpx; */
        justify-content: space-between;
        /* position: fixed;  */
    }
    
    .size-me {
        width: 70rpx;
        height: 70rpx;
    }
    
    .size-me-bgm {
        width: 40rpx;
        height: 40rpx;
    }
    
    .bgm-style {
        display: flex;
        flex-direction: row;
    }
    
    .size-bottom {
        width: 60rpx;
        height: 60rpx;
    }
    
    .face2 {
        width: 75rpx;
        height: 75rpx;
        border: 0 solid #f00;
        border-radius: 100rpx;
        background-color: #f10b2e;
    }
    
    .face {
        width: 75rpx;
        height: 75rpx;
        /* margin: 20rpx; */
        border-radius: 50%;
    }
    
    .icoBtn {
        flex: 1;
        width: 80rpx;
        height: 100%;
    }
    
    
    .comments-scoll {
        height: 1200rpx;
    }
    
    
    .comments-all {
        /* margin-top: 10px; */
          margin-bottom: 10px;  
          /* border-bottom: solid 1px gray;   */
        background-color: #141414;
        color: #e8e8e8;
    }
    
    .face-comments {
        width: 60rpx;
        height: 60rpx;
        border-radius: 50%;
        margin-left: 5px;
    }
    
    .container-comments{
        display: flex;
        
        /* margin-top: 20rpx;
        margin-left: 50rpx;
        margin-right: 50rpx;
        justify-content: space-between; */
        
    }
    
    
    .nickname-comments {
        margin-left: 10px;
    }
    
    .nickname-lbl{
        color: #a1a1a1;
    }
    
    .date-lbl{
        color: #a1a1a1;
    }
    
    .comments-content{
        margin-left: 5px;
        margin-right: 5px;
        /* margin-bottom: 10px; */
        border-bottom: solid 1px #232323;
        background-color: #141414;
    }
    
    .saySthView {
        padding: 10px;
        background-color: #141414;
        line-height: 45px;
        border-bottom: solid 1px #232323;
        color: white;
    }
    
    .saySth {
        margin-top: 10px;
        margin-left: 10px;
        font-size: 18px;
    }
    videoinfo.wxss
    const app = getApp()
    
    Page({
      data: {
        cover:"cover"
      }
    
    })
    videoinfo.js

    开源搜索视频组件的使用

      使用开源视频组件 github传送门

    searchVideo.wxml

    <include src="../../wxSearchView/wxSearchView.wxml" />

    searchVideo.wxss

    @import "../../wxSearchView/wxSearchView.wxss";
    // 1 导入js文件
    var WxSearch = require('../../wxSearchView/wxSearchView.js');
    
    
    Page({
    
      data: {
    
      },
    
      onLoad: function () {
    
        // 2 搜索栏初始化
        var that = this;
        WxSearch.init(
          that,  // 本页面一个引用
          ['校园视', 'Gary', "搞笑", "幽默", '校园', '严肃'], // 热点搜索推荐,[]表示不使用
          [],// 搜索匹配,[]表示不使用
          that.mySearchFunction, // 提供一个搜索回调函数
          that.myGobackFunction //提供一个返回回调函数
        );
    
      },
    
      // 3 转发函数,固定部分,直接拷贝即可
      wxSearchInput: WxSearch.wxSearchInput,  // 输入变化时的操作
      wxSearchKeyTap: WxSearch.wxSearchKeyTap,  // 点击提示或者关键字、历史记录时的操作
      wxSearchDeleteAll: WxSearch.wxSearchDeleteAll, // 删除所有的历史记录
      wxSearchConfirm: WxSearch.wxSearchConfirm,  // 搜索函数
      wxSearchClear: WxSearch.wxSearchClear,  // 清空函数
    
      // 4 搜索回调函数  
      mySearchFunction: function (value) {
        // do your job here
        // 示例:跳转
        wx.redirectTo({
          url: '../index/index?searchValue=' + value
        })
      },
    
      // 5 返回回调函数
      myGobackFunction: function () {
        // do your job here
        // 示例:返回
        wx.redirectTo({
          url: '../index/index?searchValue=返回'
        })
      }
    
    })
    searchVideo.js

    修改全局用户对象使用缓存

      在app.js中添加两个方法

    //设置全局用户对象
      setGlobalUserInfo:function(user){
        wx.setStorageSync("userInfo", user)
      },
    
    //获取全局用户对象
      getGlobalUserInfo: function () {
        return wx.getStorageSync("userInfo")
      }

      修改app.userInfo中的值

      

     查询接口完善以及热搜词搜索

      开发查询接口和热搜词接口

    //分页和搜索查询视频列表
        //isSaveRecord:1  需要保存  0  不需要保存或为空
        @PostMapping(value="/showAll")
        public IMoocJSONResult showAll(@RequestBody Videos video,Integer isSaveRecord ,
                Integer page) throws Exception {
            
            if(page == null) {
                page = 1;
            }
            
            PagedResult result = videoService.getAllVideos(video,isSaveRecord,page,PAGE_SIZE);
            return IMoocJSONResult.ok(result);
            
        }
        
        
        @PostMapping(value="/hot")
        public IMoocJSONResult hot() throws Exception {
            
            return IMoocJSONResult.ok(videoService.getHotwords());
        }

      VideoServiceImpl视频热搜词方法getHotwords()

        @Transactional(propagation = Propagation.SUPPORTS)
        @Override
        public List<String> getHotwords() {
            
            return searchRecordsMapper.getHotwords();
        }

      往数据库中添加一些假数据Gary数据有4条,perfect数据有2条,school数据有1条,热搜词搜索后,数据将从Gary->perfect->school顺序进行排序

      

      在searchVideo.js中进行小程序前后端连调

    onLoad: function () {
    
        // 2 搜索栏初始化
        var that = this;
    
        //查询热搜词
        var serverUrl = app.serverUrl;
        wx.request({
          url: serverUrl+'/video/hot',
          method:"POST",
          success:function(res){
              console.log(res);
              var hotList = res.data.data;
              WxSearch.init(
              that,  // 本页面一个引用
              hotList,
             // ['校园视', 'Gary', "搞笑", "幽默", '校园', '严肃'], // 热点搜索推荐,[]表示不使用
              hotList,// 搜索匹配,[]表示不使用
              that.mySearchFunction, // 提供一个搜索回调函数
              that.myGobackFunction //提供一个返回回调函数
            );
          }
        })
    
      },

    // 1 导入js文件
    var WxSearch = require('../../wxSearchView/wxSearchView.js');
    
    const app = getApp()
    
    Page({
    
      data: {
    
      },
    
      onLoad: function () {
    
        // 2 搜索栏初始化
        var that = this;
    
        //查询热搜词
        var serverUrl = app.serverUrl;
        wx.request({
          url: serverUrl+'/video/hot',
          method:"POST",
          success:function(res){
              console.log(res);
              var hotList = res.data.data;
              WxSearch.init(
              that,  // 本页面一个引用
              hotList,
             // ['校园视', 'Gary', "搞笑", "幽默", '校园', '严肃'], // 热点搜索推荐,[]表示不使用
              hotList,// 搜索匹配,[]表示不使用
              that.mySearchFunction, // 提供一个搜索回调函数
              that.myGobackFunction //提供一个返回回调函数
            );
          }
        })
    
      },
    
      // 3 转发函数,固定部分,直接拷贝即可
      wxSearchInput: WxSearch.wxSearchInput,  // 输入变化时的操作
      wxSearchKeyTap: WxSearch.wxSearchKeyTap,  // 点击提示或者关键字、历史记录时的操作
      wxSearchDeleteAll: WxSearch.wxSearchDeleteAll, // 删除所有的历史记录
      wxSearchConfirm: WxSearch.wxSearchConfirm,  // 搜索函数
      wxSearchClear: WxSearch.wxSearchClear,  // 清空函数
    
      // 4 搜索回调函数  
      mySearchFunction: function (value) {
        // do your job here
        // 示例:跳转
        wx.redirectTo({
          url: '../index/index?searchValue=' + value
        })
      },
    
      // 5 返回回调函数
      myGobackFunction: function () {
        // do your job here
        // 示例:返回
        wx.redirectTo({
          url: '../index/index?searchValue=返回'
        })
      }
    
    })
    searchVideo.js

    搜索功能整合首页列表联调

       完善searchVideo.js中搜索回调函数和返回回调函数

     // 4 搜索回调函数  
      mySearchFunction: function (value) {
        // do your job here
        // 示例:跳转
        wx.redirectTo({
          url: '../index/index?isSaveRecord=1&search=' + value
        })
      },
    
      // 5 返回回调函数
      myGobackFunction: function () {
        // do your job here
        // 示例:返回
        wx.redirectTo({
          url: '../index/index'
        })
      }

      查看数据库中videos数据库表

       VideosMapperCustom.xml中数据的模糊查询

      <select id="queryAllVideos" resultMap="BaseResultMap" parameterType="String">
      
          select v.*,u.face_image as face_image,u.nickname as nickname from videos v
          left join users u on u.id = v.user_id
          where
              1 =1
              <if test="videoDesc != null and videoDesc != '' ">
                  and v.video_desc like '%${videoDesc}%'
              </if>
              and v.status = 1
          order by v.create_time desc
      
      </select>

    const app = getApp()
    
    Page({
      data: {
        // 用于分页的属性
        totalPage:1,
        page:1,
        videoList:[],
        screenWidth: 350,
        //用于展示图片
        serverUrl:"",
        searchContent:""
      },
    
      onLoad: function (params) {
        var me = this;
        var screenWidth = wx.getSystemInfoSync().screenWidth;
    
        me.setData({
          screenWidth: screenWidth,
        });
    
        var searchContent = params.search;
        var isSaveRecord = params.isSaveRecord;
        if (isSaveRecord == null || isSaveRecord == '' || isSaveRecord==undefined){
          isSaveRecord = 0;
        }
    
        me.setData({
          searchContent: searchContent
        });
    
        //获取当前的分页数
        var page = me.data.page;
        me.getAllVideoList(page, isSaveRecord);
      },
    
      getAllVideoList: function (page, isSaveRecord){
        var me = this;
        var serverUrl = app.serverUrl;
        wx.showLoading({
          title: '请等待,加载中...',
        })
    
        var searchContent = me.data.searchContent;
    
        wx.request({
          url: serverUrl + '/video/showAll?page=' + page + "&isSaveRecord=" + isSaveRecord,
          method: "POST",
          data:{
            videoDesc: searchContent
          },
          success: function (res) {
            wx.hideLoading();
            wx.hideNavigationBarLoading();
            //停止当前页面下拉刷新
            wx.stopPullDownRefresh();
    
            console.log(res.data);
            //判断当前页面page是否是第一页,如果是第一页,那么设置videoList为空
            if (page == 1) {
              me.setData({
                videoList: []
              });
            }
    
            var videoList = res.data.data.rows;
            var newVideoList = me.data.videoList;
    
            me.setData({
              videoList: newVideoList.concat(videoList),
              page: page,
              totalPage: res.data.data.total,
              serverUrl: serverUrl
            });
    
          }
        })
      },
    
      onPullDownRefresh:function(){
        wx.showNavigationBarLoading()
        this.getAllVideoList(1,0);
      },
    
      onReachBottom:function(){
        var me = this;
        var currentPage = me.data.page;
        var totalPage = me.data.totalPage;
    
        //判断当前页数和总页数是否相等,如果相等则不需要查询
        if (currentPage == totalPage){
          wx.showToast({
            title: '已经没有视频啦~~',
            icon:"none"
          })
          return ;
        }
    
        var page = currentPage + 1;
    
        me.getAllVideoList(page,0);
      }
    
    })
    index.js
    // 1 导入js文件
    var WxSearch = require('../../wxSearchView/wxSearchView.js');
    
    const app = getApp()
    
    Page({
    
      data: {
    
      },
    
      onLoad: function () {
    
        // 2 搜索栏初始化
        var that = this;
    
        //查询热搜词
        var serverUrl = app.serverUrl;
        wx.request({
          url: serverUrl+'/video/hot',
          method:"POST",
          success:function(res){
              console.log(res);
              var hotList = res.data.data;
              WxSearch.init(
              that,  // 本页面一个引用
              hotList,
             // ['校园视', 'Gary', "搞笑", "幽默", '校园', '严肃'], // 热点搜索推荐,[]表示不使用
              hotList,// 搜索匹配,[]表示不使用
              that.mySearchFunction, // 提供一个搜索回调函数
              that.myGobackFunction //提供一个返回回调函数
            );
          }
        })
    
      },
    
      // 3 转发函数,固定部分,直接拷贝即可
      wxSearchInput: WxSearch.wxSearchInput,  // 输入变化时的操作
      wxSearchKeyTap: WxSearch.wxSearchKeyTap,  // 点击提示或者关键字、历史记录时的操作
      wxSearchDeleteAll: WxSearch.wxSearchDeleteAll, // 删除所有的历史记录
      wxSearchConfirm: WxSearch.wxSearchConfirm,  // 搜索函数
      wxSearchClear: WxSearch.wxSearchClear,  // 清空函数
    
      // 4 搜索回调函数  
      mySearchFunction: function (value) {
        // do your job here
        // 示例:跳转
        wx.redirectTo({
          url: '../index/index?isSaveRecord=1&search=' + value
        })
      },
    
      // 5 返回回调函数
      myGobackFunction: function () {
        // do your job here
        // 示例:返回
        wx.redirectTo({
          url: '../index/index'
        })
      }
    
    })
    searchVideo.js

    热搜查询联调与视频对象的播放与暂停

      微信小程序前端控制音频播放muted="{{false}}"

      在videoinfo.wxml中给<video>组件添加一个id

    <video   id="myVideo" src="http://1257737090.vod2.myqcloud.com/d7d12d2bvodcq1257737090/f42e13285285890785678595639/rG447485Zc0A.mp4"

      在videoinfo.js中使用生命周期函数onLoad(),onShow(),onHide()实现

      videoCtx:{
    
      },
    
      onLoad:function(){
        var me = this;
        me.videoCtx = wx.createVideoContext("myVideo", me);
      },
    
      onShow:function(){
        var me = this;
        me.videoCtx.play();
      },
    
      onHide:function(){
        var me = this;
        me.videoCtx.pause();
      },
    const app = getApp()
    
    Page({
      data: {
        cover:"cover"
      },
    
      videoCtx:{
    
      },
    
      onLoad:function(){
        var me = this;
        me.videoCtx = wx.createVideoContext("myVideo", me);
      },
    
      onShow:function(){
        var me = this;
        me.videoCtx.play();
      },
    
      onHide:function(){
        var me = this;
        me.videoCtx.pause();
      },
    
    
      showSearch:function(){
        wx.navigateTo({
          url: '../searchVideo/searchVideo',
        })
      }
    
    })
    videoinfo.js

    实现点击相机上传个人

      实现上传代码复用

    function uploadVideo() {
      var me = this;
    
      wx.chooseVideo({
        sourceType: ['album'],
        success: function (res) {
          console.log(res);
    
          var duration = res.duration;
          var tmpHeight = res.height;
          var tmpWidth = res.width;
          var tmpVideoUrl = res.tempFilePath;
          var tmpCoverUrl = res.thumbTempFilePath;
    
          if (duration > 11) {
            wx.showToast({
              title: '视频长度不能超过10秒...',
              icon: "none",
              duration: 2500
            })
          } else if (duration < 1) {
            wx.showToast({
              title: '视频长度太短,请上传超过1秒的视频...',
              icon: "none",
              duration: 2500
            })
          } else {
            // 打开选择bgm的页面
            wx.navigateTo({
              url: '../chooseBgm/chooseBgm?duration=' + duration
              + "&tmpHeight=" + tmpHeight
              + "&tmpWidth=" + tmpWidth
              + "&tmpVideoUrl=" + tmpVideoUrl
              + "&tmpCoverUrl=" + tmpCoverUrl
              ,
            })
          }
    
        }
      })
    
    }
    
    module.exports = {
      uploadVideo: uploadVideo
    }
    videoUtil.js

    var videoUtil = require('../../utils/videoUtil.js')
    
    const app = getApp()
    
    Page({
      data: {
        cover:"cover"
      },
    
      videoCtx:{
    
      },
    
      onLoad:function(){
        var me = this;
        me.videoCtx = wx.createVideoContext("myVideo", me);
      },
    
      onShow:function(){
        var me = this;
        me.videoCtx.play();
      },
    
      onHide:function(){
        var me = this;
        me.videoCtx.pause();
      },
    
    
      showSearch:function(){
        wx.navigateTo({
          url: '../searchVideo/searchVideo',
        })
      },
    
      upload:function(){
        videoUtil.uploadVideo();
      }
    
    })
    videoinfo.js

    首页进入视频展示页

      在videoInfo.js添加showVideoInfo()方法,当用户点击图片时候触发showVideoInfo()方法

    <image src="{{serverUrl}}{{item.coverPath}}" style='{{screenWidth}}px;height:210px;' mode="aspectFit" bindtap='showVideoInfo' data-arrindex='{{index}}'></image>
      showVideoInfo:function(e){
          var me = this;
          var videoList = me.data.videoList;
          var arrindex = e.target.dataset.arrindex;
        var videoInfo = JSON.stringify(videoList[arrindex]);
    
        wx.redirectTo({
          url: '../videoinfo/videoinfo?videoInfo='+videoInfo,
        })
      }

      在videoInfo.js中的onload()接收来自index.js中的值

      onLoad:function(params){
        var me = this;
        me.videoCtx = wx.createVideoContext("myVideo", me);
    
        //获取上一个页面传入的参数
        var videoInfo = JSON.parse(params.videoInfo);
        me.setData({
          videoInfo: videoInfo.id,
          src:app.serverUrl + videoInfo.videoPath,
          videoInfo: videoInfo
        });
      },

    const app = getApp()
    
    Page({
      data: {
        // 用于分页的属性
        totalPage:1,
        page:1,
        videoList:[],
        screenWidth: 350,
        //用于展示图片
        serverUrl:"",
        searchContent:""
      },
    
      onLoad: function (params) {
        var me = this;
        var screenWidth = wx.getSystemInfoSync().screenWidth;
    
        me.setData({
          screenWidth: screenWidth,
        });
    
        var searchContent = params.search;
        var isSaveRecord = params.isSaveRecord;
        if (isSaveRecord == null || isSaveRecord == '' || isSaveRecord==undefined){
          isSaveRecord = 0;
        }
    
        me.setData({
          searchContent: searchContent
        });
    
        //获取当前的分页数
        var page = me.data.page;
        me.getAllVideoList(page, isSaveRecord);
      },
    
      getAllVideoList: function (page, isSaveRecord){
        var me = this;
        var serverUrl = app.serverUrl;
        wx.showLoading({
          title: '请等待,加载中...',
        })
    
        var searchContent = me.data.searchContent;
    
        wx.request({
          url: serverUrl + '/video/showAll?page=' + page + "&isSaveRecord=" + isSaveRecord,
          method: "POST",
          data:{
            videoDesc: searchContent
          },
          success: function (res) {
            wx.hideLoading();
            wx.hideNavigationBarLoading();
            //停止当前页面下拉刷新
            wx.stopPullDownRefresh();
    
            console.log(res.data);
            //判断当前页面page是否是第一页,如果是第一页,那么设置videoList为空
            if (page == 1) {
              me.setData({
                videoList: []
              });
            }
    
            var videoList = res.data.data.rows;
            var newVideoList = me.data.videoList;
    
            me.setData({
              videoList: newVideoList.concat(videoList),
              page: page,
              totalPage: res.data.data.total,
              serverUrl: serverUrl
            });
    
          }
        })
      },
    
      onPullDownRefresh:function(){
        wx.showNavigationBarLoading()
        this.getAllVideoList(1,0);
      },
    
      onReachBottom:function(){
        var me = this;
        var currentPage = me.data.page;
        var totalPage = me.data.totalPage;
    
        //判断当前页数和总页数是否相等,如果相等则不需要查询
        if (currentPage == totalPage){
          wx.showToast({
            title: '已经没有视频啦~~',
            icon:"none"
          })
          return ;
        }
    
        var page = currentPage + 1;
    
        me.getAllVideoList(page,0);
      },
    
      showVideoInfo:function(e){
          var me = this;
          var videoList = me.data.videoList;
          var arrindex = e.target.dataset.arrindex;
        var videoInfo = JSON.stringify(videoList[arrindex]);
    
        wx.redirectTo({
          url: '../videoinfo/videoinfo?videoInfo='+videoInfo,
        })
      }
    
    })
    index.js
    var videoUtil = require('../../utils/videoUtil.js')
    
    const app = getApp()
    
    Page({
      data: {
        cover:"cover",
        videoId:"",
        src:"",
        videoInfo:{}
      },
    
      videoCtx:{
    
      },
    
      onLoad:function(params){
        var me = this;
        me.videoCtx = wx.createVideoContext("myVideo", me);
    
        //获取上一个页面传入的参数
        var videoInfo = JSON.parse(params.videoInfo);
        me.setData({
          videoInfo: videoInfo.id,
          src:app.serverUrl + videoInfo.videoPath,
          videoInfo: videoInfo
        });
      },
    
      onShow:function(){
        var me = this;
        me.videoCtx.play();
      },
    
      onHide:function(){
        var me = this;
        me.videoCtx.pause();
      },
    
    
      showSearch:function(){
        wx.navigateTo({
          url: '../searchVideo/searchVideo',
        })
      },
    
      upload:function(){
        videoUtil.uploadVideo();
      }
    
    })
    videoinfo.js

      为增强用户体验,实现用户上传视频时候横竖屏的转换

    onLoad:function(params){
        var me = this;
        me.videoCtx = wx.createVideoContext("myVideo", me);
    
        //获取上一个页面传入的参数
        var videoInfo = JSON.parse(params.videoInfo);
    
        var height = videoInfo.videoHeight;
        var width = videoInfo.videoWidth;
        var cover = "cover";
        if(width>=height){
          cover="";
        }
    
        me.setData({
          videoInfo: videoInfo.id,
          src:app.serverUrl + videoInfo.videoPath,
          videoInfo: videoInfo,
          cover:cover
        });
      },
    var videoUtil = require('../../utils/videoUtil.js')
    
    const app = getApp()
    
    Page({
      data: {
        cover:"cover",
        videoId:"",
        src:"",
        videoInfo:{}
      },
    
      videoCtx:{
    
      },
    
      onLoad:function(params){
        var me = this;
        me.videoCtx = wx.createVideoContext("myVideo", me);
    
        //获取上一个页面传入的参数
        var videoInfo = JSON.parse(params.videoInfo);
    
        var height = videoInfo.videoHeight;
        var width = videoInfo.videoWidth;
        var cover = "cover";
        if(width>=height){
          cover="";
        }
    
        me.setData({
          videoInfo: videoInfo.id,
          src:app.serverUrl + videoInfo.videoPath,
          videoInfo: videoInfo,
          cover:cover
        });
      },
    
      onShow:function(){
        var me = this;
        me.videoCtx.play();
      },
    
      onHide:function(){
        var me = this;
        me.videoCtx.pause();
      },
    
    
      showSearch:function(){
        wx.navigateTo({
          url: '../searchVideo/searchVideo',
        })
      },
    
      upload:function(){
        videoUtil.uploadVideo();
      }
    
    })
    videoinfo.js
    (如需转载学习,请标明出处)
  • 相关阅读:
    [LeetCode]String主题系列{第5,6题}
    [LeetCode]Math主题系列{第7,9,13,273题}
    [LeetCode]LinkedList主题系列{第2题}
    [LeetCode]HashTable主题系列{第3,36,49,94,136,138,187,202,204,205,290,347,389,409,438,451,463,500,508,560,594,599题}
    由于博客园的道路越来越像CSDN了,已经不再是当年的博客园了,决定退出博客园,后续建立自己的博客站点。
    Revit二次开发——非模态窗口的事件处理
    Revit二开---Schemachema扩展数据
    Revit二开---ViewFamily视图类型枚举
    CAD二开---扩展数据XData
    CAD二开---框选文字批量对齐
  • 原文地址:https://www.cnblogs.com/1138720556Gary/p/10701600.html
Copyright © 2011-2022 走看看