微信小程序_(校园视)开发视频的展示页_上
微信小程序_(校园视) 开发用户注册登陆 传送门
微信小程序_(校园视) 开发上传视频业务 传送门
微信小程序_(校园视) 开发视频的展示页-上 传送门
微信小程序_(校园视) 开发视频的展示页-下 传送门
小程序首页视频列表开发
校园视小程序首页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
微信小程序_(校园视)开发视频的展示页_上的更多相关文章
- 微信小程序_(校园视)开发视频的展示页_下
微信小程序_(校园视) 开发用户注册登陆 传送门 微信小程序_(校园视) 开发上传视频业务 传送门 微信小程序_(校园视) 开发视频的展示页-上 传送门 微信小程序_(校园视) 开发视频的展示页-下 ...
- 微信小程序_(校园视)开发上传视频业务
微信小程序_(校园视) 开发用户注册登陆 传送门 微信小程序_(校园视) 开发上传视频业务 传送门 微信小程序_(校园视) 开发视频的展示页-上 传送门 微信小程序_(校园视) 开发视频的展示页-下 ...
- 微信小程序_(校园视)开发用户注册登陆
微信小程序_(校园视) 开发用户注册登陆 传送门 微信小程序_(校园视) 开发上传视频业务 传送门 微信小程序_(校园视) 开发视频的展示页-上 传送门 微信小程序_(校园视) 开发视频的展示页-下 ...
- 从微信小程序到鸿蒙js开发【13】——list加载更多&回到顶部
鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 目录: 1.list加载更多 2.list回到顶部 3.<从微信小程序到鸿蒙js开发>系列文章合集 1.list加 ...
- 微信小程序购物商城系统开发系列-目录结构
上一篇我们简单介绍了一下微信小程序的IDE(微信小程序购物商城系统开发系列-工具篇),相信大家都已经蠢蠢欲试建立一个自己的小程序,去完成一个独立的商城网站. 先别着急我们一步步来,先尝试下写一个自己的 ...
- 微信小程序购物商城系统开发系列-工具篇
微信小程序开放公测以来,一夜之间在各种技术社区中就火起来啦.对于它 估计大家都不陌生了,对于它未来的价值就不再赘述,简单一句话:可以把小程序简单理解为一个新的操作系统.新的生态,未来大部分应用场景都将 ...
- 微信小程序购物商城系统开发系列
微信小程序购物商城系统开发系列 微信小程序开放公测以来,一夜之间在各种技术社区中就火起来啦.对于它 估计大家都不陌生了,对于它未来的价值就不再赘述,简单一句话:可以把小程序简单理解为一个新的操作系统. ...
- 从微信小程序到鸿蒙js开发【11】——页面路由
目录: 1.router.push()&wx.navigateTo() 2.router.replace()&wx.redirectTo() 3.router.back()&w ...
- 从微信小程序到鸿蒙js开发【12】——storage缓存&自动登录
鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 正文: 在应用开发时,我们常需要将一些数据缓存到本地,以提升用户体验.比如在一个电商的app中,如果希望用户登录成功后,下次打 ...
随机推荐
- Vue用递归实现一个消除输入框表情符的自定义directive
最近项目中有一个需求,所有的文本输入框需要过滤掉表情符号,但是觉得每次表单验证的时候去判断,有点麻烦.于是我想到了自定义一个指令,后续遇到需要删除表情符号的输入框,直接通过指令将表情符号删除就好了,方 ...
- JS基础_条件运算符
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- git pull文件时和本地文件冲突 方法之一
1.先将本地修改存储起来 2.pull内容 3.还原暂存的内容 4.解决文件中冲突的的部分 打开 dsa.txt 文件手动解决冲突. 其中Updated upstream 和=====之间的内容就是p ...
- 解决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类型 ...
- web项目部署在centos 7验证码显示不出来解决方案
今天把项目部署在centos7上,发现验证码显示不出来,看了一下tomcat日志 Exception in thread "http-nio-8080-exec-3" java.l ...
- JavaJDBC【一、概述】
其实这个内容在学习java基础的时候就有看过了,只是没有详细整理,在这再整理一下 数据库操作对于任何一门后端语言来说都是很重要的 JDBC:Java Data Base Connectivity 内容 ...
- mysql数据库:mysql增删改、单表、多表及子查询
一.数据增删改 二.单表查询 三.正表达式匹配 四.多表查询 五.子查询 一..数据增删改 增加 insert [into] 表名[(可选字段名)] values(一堆值1),( ...
- python面向编程:类继承、继承案例、单继承下属性查找、super方法
一.类的继承 二.基于继承解决类与类的代码冗余问题 三.在单继承背景下属性的查找 四.super的方法 一.类的继承 1.什么是继承? 在程序中继承是一种新建子类的方法的方式,新创建的类成为子类\派生 ...
- mysql服务脚本
#!/bin/bash #*************************** #* copyleft huihui 2015-08-11 #**************************** ...
- Scala(一)——基本类型
Scala语言快速入门(基本类型) (参考视频:av39126512,韩顺平281集scala精讲) 一.Linux和Windows环境安装 这部分跳过,直接使用IDEA进行搭建,和其他编程语言配置差 ...