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

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

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

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

小程序首页视频列表开发

  校园视小程序首页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='width:{{screenWidth}}px;height:210px;' class='back-img'>
<image src="http://localhost:8081/190502AYNKPFRDD4/video/wx70d559ac5d37dd78.o6zAJs59F12Wz0jOMOX2L2uFIE_w.9StRAIr1vMWvc4e5d48a6fc4fabc84946439cb0983d0.jpg" style='width:{{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='width:{{screenWidth}}px;height:210px;' class='back-img'>
<image src="{{serverUrl}}{{item.coverPath}}" style='width:{{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='width:{{screenWidth}}px;height:210px;' class='back-img'>
<image src="{{serverUrl}}{{item.coverPath}}" style='width:{{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='width:{{screenWidth}}px;height:210px;' class='back-img'>
<image src="{{serverUrl}}{{item.coverPath}}" style='width:{{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='width: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='width: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='width:50rpx;height:50rpx;' bindtap='upload'></cover-image> <!-- 搜索按钮 -->
<cover-image src='../resource/images/search.png' style='width: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='width: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='width:100%;height:100%;'
objectFit='{{cover}}'
> <cover-view class='container'>
<!-- 上传视频 --> <cover-image src='../resource/images/camera.png' style='width:50rpx;height:50rpx;' bindtap='upload'></cover-image> <!-- 搜索按钮 -->
<cover-image src='../resource/images/search.png' style='width: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:;
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='width:{{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

微信小程序_(校园视)开发视频的展示页_上的更多相关文章

  1. 微信小程序_(校园视)开发视频的展示页_下

    微信小程序_(校园视) 开发用户注册登陆 传送门 微信小程序_(校园视) 开发上传视频业务 传送门 微信小程序_(校园视) 开发视频的展示页-上 传送门 微信小程序_(校园视) 开发视频的展示页-下 ...

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

    微信小程序_(校园视) 开发用户注册登陆 传送门 微信小程序_(校园视) 开发上传视频业务 传送门 微信小程序_(校园视) 开发视频的展示页-上 传送门 微信小程序_(校园视) 开发视频的展示页-下 ...

  3. 微信小程序_(校园视)开发用户注册登陆

    微信小程序_(校园视) 开发用户注册登陆 传送门 微信小程序_(校园视) 开发上传视频业务 传送门 微信小程序_(校园视) 开发视频的展示页-上 传送门 微信小程序_(校园视) 开发视频的展示页-下 ...

  4. 从微信小程序到鸿蒙js开发【13】——list加载更多&回到顶部

    鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 目录: 1.list加载更多 2.list回到顶部 3.<从微信小程序到鸿蒙js开发>系列文章合集 1.list加 ...

  5. 微信小程序购物商城系统开发系列-目录结构

    上一篇我们简单介绍了一下微信小程序的IDE(微信小程序购物商城系统开发系列-工具篇),相信大家都已经蠢蠢欲试建立一个自己的小程序,去完成一个独立的商城网站. 先别着急我们一步步来,先尝试下写一个自己的 ...

  6. 微信小程序购物商城系统开发系列-工具篇

    微信小程序开放公测以来,一夜之间在各种技术社区中就火起来啦.对于它 估计大家都不陌生了,对于它未来的价值就不再赘述,简单一句话:可以把小程序简单理解为一个新的操作系统.新的生态,未来大部分应用场景都将 ...

  7. 微信小程序购物商城系统开发系列

    微信小程序购物商城系统开发系列 微信小程序开放公测以来,一夜之间在各种技术社区中就火起来啦.对于它 估计大家都不陌生了,对于它未来的价值就不再赘述,简单一句话:可以把小程序简单理解为一个新的操作系统. ...

  8. 从微信小程序到鸿蒙js开发【11】——页面路由

    目录: 1.router.push()&wx.navigateTo() 2.router.replace()&wx.redirectTo() 3.router.back()&w ...

  9. 从微信小程序到鸿蒙js开发【12】——storage缓存&自动登录

    鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 正文: 在应用开发时,我们常需要将一些数据缓存到本地,以提升用户体验.比如在一个电商的app中,如果希望用户登录成功后,下次打 ...

随机推荐

  1. Vue用递归实现一个消除输入框表情符的自定义directive

    最近项目中有一个需求,所有的文本输入框需要过滤掉表情符号,但是觉得每次表单验证的时候去判断,有点麻烦.于是我想到了自定义一个指令,后续遇到需要删除表情符号的输入框,直接通过指令将表情符号删除就好了,方 ...

  2. JS基础_条件运算符

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. git pull文件时和本地文件冲突 方法之一

    1.先将本地修改存储起来 2.pull内容 3.还原暂存的内容 4.解决文件中冲突的的部分 打开 dsa.txt 文件手动解决冲突. 其中Updated upstream 和=====之间的内容就是p ...

  4. 解决IDEA报错Could not autowire. There is more than one bean of 'xxx' type

    更新项目之后IDEA突然出现了这样的报错信息.显示Could not autowire. There is more than one bean of 'xxx' type.这个错误的意思是xxx类型 ...

  5. web项目部署在centos 7验证码显示不出来解决方案

    今天把项目部署在centos7上,发现验证码显示不出来,看了一下tomcat日志 Exception in thread "http-nio-8080-exec-3" java.l ...

  6. JavaJDBC【一、概述】

    其实这个内容在学习java基础的时候就有看过了,只是没有详细整理,在这再整理一下 数据库操作对于任何一门后端语言来说都是很重要的 JDBC:Java Data Base Connectivity 内容 ...

  7. mysql数据库:mysql增删改、单表、多表及子查询

    一.数据增删改 二.单表查询 三.正表达式匹配 四.多表查询 五.子查询       一..数据增删改     增加  insert [into] 表名[(可选字段名)] values(一堆值1),( ...

  8. python面向编程:类继承、继承案例、单继承下属性查找、super方法

    一.类的继承 二.基于继承解决类与类的代码冗余问题 三.在单继承背景下属性的查找 四.super的方法 一.类的继承 1.什么是继承? 在程序中继承是一种新建子类的方法的方式,新创建的类成为子类\派生 ...

  9. mysql服务脚本

    #!/bin/bash #*************************** #* copyleft huihui 2015-08-11 #**************************** ...

  10. Scala(一)——基本类型

    Scala语言快速入门(基本类型) (参考视频:av39126512,韩顺平281集scala精讲) 一.Linux和Windows环境安装 这部分跳过,直接使用IDEA进行搭建,和其他编程语言配置差 ...