Video display content is video screenshots, user's avatar, user's nickname, all need a combination. Source code: https://github.com/limingios/wxProgram.git in wx-spring boot and No.15
Getting System Information
- Introduction to Official Website
https://developers.weixin.qq.com/miniprogram/dev/dev/api/system/system-info/wx.getSystemInfo.html
- Getting System Information
Because the screen sizes of mobile phones are different now, display adaptation is a big problem. How to get the corresponding cell phone's pixel value is the first choice for adaptation. The response information is obtained through the pixel value, and the dynamic control adaption is achieved.
Background Procedure
Customize the association query, query the corresponding composite data through the paging component, and the controller provides the paging interface.
- java Paging Tool
package com.idig8.utils; import java.util.List; /** * @Description: Paging-encapsulated data format */ public class PagedResult { private int page; // page private int total; // PageCount private long records; // Total number of records private List<?> rows; // Content displayed on each line 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; } }
- java component principle
By means of interception, when executing an sql statement, the query limit is added when querying the sql statement according to the dialect of different databases. PageHelper is a useful open source free Mybatis third-party physical paging plug-in. Actually, I don't want to add the word "easy to use", but in order to praise the plug-in author's noble spirit of open source free, I did not hesitate to add the word "good to use" as a compliment. Originally thought that paging plug-in should be very simple, but PageHelper is much more complex than I thought. It is powerful and thorough, so powerful that users may not need so many functions, thoroughly to a reference can be dual-purpose. However, I think that as a paging plug-in, it is essential to complete the physical paging task. Many other intelligences are not necessary. It is foolish enough to maintain it. The professional term is "stupid". Simplicity is beauty.
- Adding Vo Return Parameter Entities
package com.idig8.pojo.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 username; private String faceImage; private String nickname; public String getId() { return id; } /** * @param id */ public void setId(String id) { this.id = id; } /** * Get the Publisher id * * @return user_id - Publisher id */ public String getUserId() { return userId; } /** * Setting the Publisher id * * @param userId Publisher id */ public void setUserId(String userId) { this.userId = userId; } /** * Getting information about users using audio * * @return audio_id - User's Use of Audio Information */ public String getAudioId() { return audioId; } /** * Setting up user's audio information * * @param audioId User's Use of Audio Information */ public void setAudioId(String audioId) { this.audioId = audioId; } /** * Getting Video Description * * @return video_desc - Video Description */ public String getVideoDesc() { return videoDesc; } /** * Setting Video Description * * @param videoDesc Video Description */ public void setVideoDesc(String videoDesc) { this.videoDesc = videoDesc; } /** * Access to Video Storage Path * * @return video_path - Video Storage Path */ public String getVideoPath() { return videoPath; } /** * Setting the path of video storage * * @param videoPath Video Storage Path */ public void setVideoPath(String videoPath) { this.videoPath = videoPath; } /** * Get the number of video seconds * * @return video_seconds - Video seconds */ public Float getVideoSeconds() { return videoSeconds; } /** * Set the number of video seconds * * @param videoSeconds Video seconds */ public void setVideoSeconds(Float videoSeconds) { this.videoSeconds = videoSeconds; } /** * Getting Video Width * * @return video_width - Video Width */ public Integer getVideoWidth() { return videoWidth; } /** * Setting Video Width * * @param videoWidth Video Width */ public void setVideoWidth(Integer videoWidth) { this.videoWidth = videoWidth; } /** * Getting Video Height * * @return video_height - Video Height */ public Integer getVideoHeight() { return videoHeight; } /** * Setting Video Height * * @param videoHeight Video Height */ public void setVideoHeight(Integer videoHeight) { this.videoHeight = videoHeight; } /** * Getting a Video Cover Map * * @return cover_path - Video Cover Map */ public String getCoverPath() { return coverPath; } /** * Setting Video Cover Map * * @param coverPath Video Cover Map */ public void setCoverPath(String coverPath) { this.coverPath = coverPath; } /** * Quantity of likes/compliments * * @return like_counts - Number of likes/compliments */ public Long getLikeCounts() { return likeCounts; } /** * Set the number of likes/compliments * * @param likeCounts Number of likes/compliments */ public void setLikeCounts(Long likeCounts) { this.likeCounts = likeCounts; } /** * Get the video status: 1,Successful release 2,No playback, administrator operation * * @return status - Video status: 1,Successful release 2,No playback, administrator operation */ public Integer getStatus() { return status; } /** * Set video status: 1,Successful release 2,No playback, administrator operation * * @param status Video status: 1,Successful release 2,No playback, administrator operation */ public void setStatus(Integer status) { this.status = status; } /** * Get the creation time * * @return create_time - Creation time */ public Date getCreateTime() { return createTime; } /** * Set the creation time * * @param createTime Creation time */ public void setCreateTime(Date createTime) { this.createTime = createTime; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getFaceImage() { return faceImage; } public void setFaceImage(String faceImage) { this.faceImage = faceImage; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } }
- Database query java mapper
package com.idig8.mapper; import java.util.List; import com.idig8.pojo.Videos; import com.idig8.pojo.vo.VideosVO; import com.idig8.utils.MyMapper; public interface VideosUsersMapper extends MyMapper<VideosVO> { public List<VideosVO> queryAllVideos(); }
- xml of Mybatis database
<?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.idig8.mapper.VideosUsersMapper" > <resultMap id="BaseResultMap" type="com.idig8.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="username" property="username" jdbcType="VARCHAR" /> <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,u.username,u.nickname from videos v left join users u on v.user_id = u.id where 1 = 1 and v.status = 1 order by v.create_time </select> </mapper>
- Interface and implementation of service
package com.idig8.service; import com.idig8.pojo.Videos; import com.idig8.utils.PagedResult; public interface VideoService { /** * Save Video Information * @param Id * @return */ public String saveVideo(Videos video); /** * Analyzing Query Video List * @param page * @param pageSize * @return */ public PagedResult getAllVideos(Integer page,Integer pageSize); }
package com.idig8.service.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.github.pagehelper.autoconfigure.PageHelperAutoConfiguration; import com.idig8.mapper.VideosMapper; import com.idig8.mapper.VideosUsersMapper; import com.idig8.pojo.Videos; import com.idig8.pojo.vo.VideosVO; import com.idig8.service.VideoService; import com.idig8.utils.PagedResult; @Service public class VideoServiceImpl implements VideoService { @Autowired private VideosMapper videosMapper; @Autowired private VideosUsersMapper videosUsersMapper; @Autowired private Sid sid; @Transactional(propagation =Propagation.REQUIRED) public String saveVideo(Videos video){ String id = sid.nextShort(); video.setId(id); videosMapper.insertSelective(video); return id; } @Override @Transactional(propagation =Propagation.SUPPORTS) public PagedResult getAllVideos(Integer page, Integer pageSize) { PageHelper.startPage(page,pageSize); List<VideosVO> list = videosUsersMapper.queryAllVideos(); PageInfo<VideosVO> pageList =new PageInfo<>(list); PagedResult result = new PagedResult(); result.setPage(page); result.setTotal(pageList.getPages()); result.setRows(list); result.setRecords(pageList.getTotal()); return result; } }
- Development of controller
package com.idig8.controller; import java.io.File; import java.util.Date; import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import com.idig8.pojo.Bgm; import com.idig8.pojo.Videos; import com.idig8.service.BgmService; import com.idig8.service.VideoService; import com.idig8.utils.FetchVideoCover; import com.idig8.utils.JSONResult; import com.idig8.utils.MergeVideoMp3; import com.idig8.utils.PagedResult; import com.idig8.utils.enums.VideoStatusEnum; import com.idig8.utils.file.FileUtil; 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="Interface of Video-related Services", tags= {"Video related services controller"}) @RequestMapping("/video") public class VideoController extends BasicController { @Autowired private BgmService bgmService; @Autowired private VideoService videosService; @Value("${server.file.path}") private String fileSpace; @Value("${server.ffmpeg.path}") private String ffmpegexe; @ApiOperation(value="Upload Video", notes="Interface for uploading video") @ApiImplicitParams({ @ApiImplicitParam(name="userId", value="user id", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="bgmId", value="Background music id", required=false, dataType="String", paramType="form"), @ApiImplicitParam(name="videoSeconds", value="Background music playback length", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="videoWidth", value="Video Width", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="videoHeight", value="Video Height", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="desc", value="Video Description", required=false, dataType="String", paramType="form") }) @PostMapping(value="/upload", headers="content-type=multipart/form-data") public JSONResult upload(String userId, String bgmId, double videoSeconds, int videoWidth, int videoHeight, String desc, @ApiParam(value="Short Video", required=true) MultipartFile file) throws Exception { if (StringUtils.isBlank(userId)) { return JSONResult.errorMsg("user id Can't be empty..."); } // Namespaces saved by files String fileName = file.getOriginalFilename(); // Relative paths saved to the database String path = ""; String videOutPath = ""; String ImagePath = ""; try { path = FileUtil.uploadFile(file.getBytes(), fileSpace, fileName); } catch (Exception e) { e.getStackTrace(); return JSONResult.errorMsg(e.getMessage()); } if(StringUtils.isNotBlank(bgmId)){ Bgm bgm = bgmService.queryBgmById(bgmId); String mp3BgmPath = fileSpace + bgm.getPath(); MergeVideoMp3 mergeVideoMp3 = new MergeVideoMp3(ffmpegexe); String videOutPathName = UUID.randomUUID().toString()+".mp4"; File targetFile = new File(fileSpace + userId); if (!targetFile.exists()) { targetFile.mkdirs(); } videOutPath = "/"+userId+"/"+videOutPathName; String videoInput = fileSpace +path; mergeVideoMp3.convertor(videoInput, mp3BgmPath, videoSeconds, fileSpace +videOutPath); }else{ videOutPath = path; } ImagePath = "/"+userId+"/"+UUID.randomUUID().toString()+".jpg";; FetchVideoCover fetchVideoCover = new FetchVideoCover(ffmpegexe); fetchVideoCover.getCover(fileSpace +videOutPath, fileSpace +ImagePath); Videos videos = new Videos(); videos.setAudioId(bgmId); videos.setCreateTime(new Date()); videos.setVideoDesc(desc); videos.setId(UUID.randomUUID().toString()); videos.setUserId(userId); videos.setVideoHeight(videoHeight); videos.setVideoWidth(videoWidth); videos.setVideoPath(videOutPath); videos.setCoverPath(ImagePath); videos.setStatus(VideoStatusEnum.SUCCESS.value); videosService.saveVideo(videos); return JSONResult.ok(path); } @PostMapping(value="/showAll") @ApiOperation(value="Video List", notes="Paginated Video List") @ApiImplicitParam(name="page", value="Page number", dataType="String", paramType="query") public JSONResult upload( Integer page) throws Exception { if(page == null){ page = 1; } PagedResult result = videosService.getAllVideos(page, PAGE_SIZE); return JSONResult.ok(result); } }
Page Development of Small Programs
<view wx:for="{{videoList}}" 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.faceImage}}"></image> <view class="nickname">{{item.nickname}}</view> </view> </view> </view>
.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; }
const app = getApp() Page({ data: { // Attributes for paging 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 }); // Get the current number of pages var page = me.data.page; var me = this; var serverUrl = app.serverUrl; wx.showLoading({ title: 'Please wait, loading...', }); 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); // Determine if the current page page is the first page and if it is the first page, set the videoList to empty 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 }); } }) } })
PS: It mainly talks about the steps of association query. First, it establishes a VO class. Then mapper associates VO class, adds corresponding xml file to return VO class, adds paging plug-in in service, inquires VO class, and sets it through paging plug-in.
The page acquires the width of the mobile phone through the Wechat component, adapts it dynamically by the width, and calls the interface to return the content to display the data iteratively through the block method. Next time say pull-down and pull-down refresh.