一、視頻組件與api介紹
video
視頻。該組件是原生組件,使用時請注意相關限制。
屬性名 | 類型 | 默認值 | 說明 | 最低版本 |
---|---|---|---|---|
src | String | 要播放視頻的資源地址,支持雲文件ID(2.2.3起) | ||
initial-time | Number | 指定視頻初始播放位置 | 1.6.0 | |
duration | Number | 指定視頻時長 | 1.1.0 | |
controls | Boolean | true | 是否顯示默認播放控件(播放/暫停按鈕、播放進度、時間) | |
danmu-list | Object Array | 彈幕列表 | ||
danmu-btn | Boolean | false | 是否顯示彈幕按鈕,只在初始化時有效,不能動態變更 | |
enable-danmu | Boolean | false | 是否展示彈幕,只在初始化時有效,不能動態變更 | |
autoplay | Boolean | false | 是否自動播放 | |
loop | Boolean | false | 是否循環播放 | 1.4.0 |
muted | Boolean | false | 是否靜音播放 | 1.4.0 |
page-gesture | Boolean | false | 在非全屏模式下,是否開啟亮度與音量調節手勢 | 1.6.0 |
direction | Number | 設置全屏時視頻的方向,不指定則根據寬高比自動判斷。有效值為 0(正常豎向), 90(屏幕逆時針90度), -90(屏幕順時針90度) | 1.7.0 | |
show-progress | Boolean | true | 若不設置,寬度大於240時才會顯示 | 1.9.0 |
show-fullscreen-btn | Boolean | true | 是否顯示全屏按鈕 | 1.9.0 |
show-play-btn | Boolean | true | 是否顯示視頻底部控制欄的播放按鈕 | 1.9.0 |
show-center-play-btn | Boolean | true | 是否顯示視頻中間的播放按鈕 | 1.9.0 |
enable-progress-gesture | Boolean | true | 是否開啟控制進度的手勢 | 1.9.0 |
objectFit | String | contain | 當視頻大小與 video 容器大小不一致時,視頻的表現形式。contain:包含,fill:填充,cover:覆蓋 | |
poster | String | 視頻封面的圖片網絡資源地址或雲文件ID(2.2.3起支持)如果 controls 屬性值為 false 則設置 poster 無效 | ||
bindplay | EventHandle | 當開始/繼續播放時觸發play事件 | ||
bindpause | EventHandle | 當暫停播放時觸發 pause 事件 | ||
bindended | EventHandle | 當播放到末尾時觸發 ended 事件 | ||
bindtimeupdate | EventHandle | 播放進度變化時觸發,event.detail = {currentTime, duration} 。觸發頻率 250ms 一次 | ||
bindfullscreenchange | EventHandle | 視頻進入和退出全屏時觸發,event.detail = {fullScreen, direction},direction取為 vertical 或 horizontal | 1.4.0 | |
bindwaiting | EventHandle | 視頻出現緩沖時觸發 | 1.7.0 | |
binderror | EventHandle | 視頻播放出錯時觸發 | 1.7.0 |
<video />
默認寬度300px、高度225px,可通過wxss設置寬高。
二、視頻展示頁開發1-視頻展示頁面
<view style='width:100%;height:100%;'> <video src="http://hdz.natapp1.cc/18100179DXRC6ZXP/video/d7349f63-7d2b-46b8-8742-ca02752ec24a.mp4" muted="{{true}}" controls="{{false}}" autoplay="{{true}}" loap="{{true}}" enable-progress-gesture="{{false}}" style='width:100%;height:100%;' objectFit='{{cover}}' > </video> </view>
const app = getApp() Page({ data: { cover: "cover" } })
三、視頻展示頁開發1-圖標放置
cover-view
基礎庫 1.4.0 開始支持,低版本需做兼容處理。
覆蓋在原生組件之上的文本視圖,可覆蓋的原生組件包括map
、video
、canvas
、camera
、live-player
、live-pusher
,只支持嵌套cover-view
、cover-image
,可在cover-view
中使用button
。
屬性名 | 類型 | 默認值 | 說明 | 最低版本 |
---|---|---|---|---|
scroll-top | Number | 設置頂部滾動偏移量,僅在設置了 overflow-y: scroll 成為滾動元素后生效 | 2.1.0 |
cover-image
基礎庫 1.4.0 開始支持,低版本需做兼容處理。
覆蓋在原生組件之上的圖片視圖,可覆蓋的原生組件同cover-view
,支持嵌套在cover-view里。
屬性名 | 類型 | 默認值 | 說明 | 最低版本 |
---|---|---|---|---|
src | String | 圖標路徑,支持臨時路徑、網絡地址(1.6.0起支持)、雲文件ID(2.2.3起支持)。暫不支持base64格式。 | ||
bindload | EventHandle | 圖片加載成功時觸發 | 2.1.0 | |
binderror | EventHandle | 圖片加載失敗時觸發 | 2.1.0 |
Bug & Tips
tip
: 基礎庫 2.2.4 起支持 touch 相關事件,也可使用 hover-class 設置點擊態tip
: 基礎庫 2.1.0 起支持設置scale
rotate
的 css 樣式,包括 transition 動畫tip
: 基礎庫 1.9.90 起cover-view
支持overflow: scroll
,但不支持動態更新overflow
tip
: 基礎庫 1.9.90 起最外層cover-view
支持position: fixed
tip
: 基礎庫 1.9.0 起支持插在view
等標簽下。在此之前只可嵌套在原生組件map
、video
、canvas
、camera
內,避免嵌套在其他組件內。tip
: 基礎庫 1.6.0 起支持css transition動畫,transition-property
只支持transform (translateX, translateY)
與opacity
。tip
: 基礎庫 1.6.0 起支持css opacity。tip
: 事件模型遵循冒泡模型,但不會冒泡到原生組件。tip
: 文本建議都套上cover-view標簽,避免排版錯誤。tip
: 只支持基本的定位、布局、文本樣式。不支持設置單邊的border
、background-image
、shadow
、overflow: visible
等。tip
: 建議子節點不要溢出父節點tip
: 默認設置的樣式有:white-space: nowrap;
line-height: 1.2;
display: block;
bug
: 自定義組件嵌套cover-view
時,自定義組件的 slot 及其父節點暫不支持通過 wx:if 控制顯隱,否則會導致cover-view
不顯示
<view style='width:100%;height:100%;'> <video src="http://hdz.natapp1.cc/18100179DXRC6ZXP/video/d7349f63-7d2b-46b8-8742-ca02752ec24a.mp4" muted="{{true}}" controls="{{false}}" autoplay="{{true}}" loap="{{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='{{serverUrl}}{{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/mine.png' class="size-bottom" bindtap='showMine'></cover-image> </cover-view> </video> </view>
page { height: 100%; background-color: #141414; } .container { display: flex; margin-top: 20rpx; margin-left: 50rpx; margin-right: 50rpx; justify-content: space-between; } .container-me { margin-top: 360rpx; margin-left: 50rpx; width: 80rpx; } .container-words { /* display: flex; flex-direction: column; */ margin-top: 60rpx; margin-left: 50rpx; width: 100%; color: white; font-size: 14px; } .inputText { background-color: gainsboro; height: 35px; } .video-desc { width: 600rpx; height: 100rpx; white-space: pre-wrap; } .container-bottom { /* bottom: 10px; */ display: flex; margin-top: 60rpx; margin-left: 50rpx; margin-right: 50rpx; /* margin-bottom: 10rpx; */ justify-content: space-between; /* position: fixed; */ } .size-me { width: 70rpx; height: 70rpx; } .size-me-bgm { width: 40rpx; height: 40rpx; } .bgm-style { display: flex; flex-direction: row; } .size-bottom { width: 60rpx; height: 60rpx; } .face2 { width: 75rpx; height: 75rpx; border: 0 solid #f00; border-radius: 100rpx; background-color: #f10b2e; } .face { width: 75rpx; height: 75rpx; /* margin: 20rpx; */ border-radius: 50%; } .icoBtn { flex: 1; width: 80rpx; height: 100%; } .comments-scoll { height: 1200rpx; } .comments-all { /* margin-top: 10px; */ margin-bottom: 10px; /* border-bottom: solid 1px gray; */ background-color: #141414; color: #e8e8e8; } .face-comments { width: 60rpx; height: 60rpx; border-radius: 50%; margin-left: 5px; } .container-comments{ display: flex; /* margin-top: 20rpx; margin-left: 50rpx; margin-right: 50rpx; justify-content: space-between; */ } .nickname-comments { margin-left: 10px; } .nickname-lbl{ color: #a1a1a1; } .date-lbl{ color: #a1a1a1; } .comments-content{ margin-left: 5px; margin-right: 5px; /* margin-bottom: 10px; */ border-bottom: solid 1px #232323; background-color: #141414; } .saySthView { padding: 10px; background-color: #141414; line-height: 45px; border-bottom: solid 1px #232323; color: white; } .saySth { margin-top: 10px; margin-left: 10px; font-size: 18px; }
四、開源搜索視頻組件的使用
1、地址:https://github.com/mindawei/wsSearchView
2、使用簡介
QuickStart
- 拷貝項目根目錄的wxSearchView文件夾到你項目的根目錄下(也可以其它位置)。
- 在你的wxss文件里導入組件的樣式(文件位置為相對位置):
@import "../../wxSearchView/wxSearchView.wxss";
- 在你的wxml文件里導入組件(文件位置為相對位置):
<include src="../../wxSearchView/wxSearchView.wxml" />
- 在你的js文件里面添加以下代碼,主要包括以下5個部分:
- 導入js文件
- 搜索欄初始化
- 轉發函數
- 搜索回調函數
- 返回回調函數
// 1 導入js文件 var WxSearch = require('../../wxSearchView/wxSearchView.js'); Page({ data: {}, onLoad: function () { // 2 搜索欄初始化 var that = this; WxSearch.init( that, // 本頁面一個引用 ['杭州', '嘉興', "海寧", "桐鄉", '寧波', '金華'], // 熱點搜索推薦,[]表示不使用 ['湖北', '湖南', '北京', "南京"],// 搜索匹配,[]表示不使用 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=返回' }) } })
說明
回調函數
為了方便調用,提高開發效率,組件實際上只是提供了兩個回調接口,開發者也只需要提供這兩個函數,介紹如下:
- 搜索回調函數,下面是一個例子。當用戶點擊歷史記錄、搜索熱點、搜索提示、搜索按鈕時,都會回調開發者提供的函數接口,開發者拿到參數后可以跳到另一個頁面展示查詢結果。
mySearchFunction: function (value) { // do your job here }
- 返回回調函數,下面是一個例子。搜索框邊上的按鈕有兩個角色,當輸入為空的時候,是一個返回按鈕;當輸入不為空時,是一個搜索按鈕。當點擊返回按鈕時,就會回調開發者提供的函數,這里可以跳回到指定頁面。
myGobackFunction: function () { // do your job here }
頁面關系
為了避免輸入法遮擋的影響,該組件適合放在一個獨立的搜索頁面中。該搜索頁面與其他頁面間的關系如下圖所示:
- 搜索入口:搜索頁面需要一個導入的入口,這個入口可以是一個搜索框,也可以是一些搜索按鈕。在本項目中,搜索入口頁面是index頁面,搜索入口是一個搜索框。
- 搜索頁面:搜索組件是放在搜索頁面中的,直接按照QuickStart中的描述導入即可。搜索頁面可以通過返回回調函數跳轉到之前的頁面中去,可以通過搜索回調函數跳轉到具體展示結果的頁面中去。在本項目中,搜索頁面是search頁面,開發者可以進行參考或直接拷貝。
- 搜索結果:搜索結果頁面根據搜索頁面傳遞過來的參數展示搜索結果。本項目中,為了簡單,將搜索入口和搜索結果統一成一個index頁面,開發者可以參考index頁面中onLoad函數來查看參數如何獲取。
界面修改位置
為了提高開發者的開發效率,下表列出了一些常用修改的位置。
界面效果 | 修改位置 |
---|---|
標簽寬度 | wxSearchView.wxss -> .wxSearchKeyItem -> flex |
標簽背景色 | wxSearchView.wxss -> .wxSearchKeyItem -> background-color |
頁面背景色 | wxSearchView.wxss -> .wxSearch -> background-color |
提示面板背景色 | wxSearchView.wxss -> .wxSearchInner -> background-color |
返回按鈕不需要 | wxSearchView.wxml -> 搜索 weui-search-bar__cancel-btn |
搜索提示修改 | wxSearchView.wxml -> 搜索 wxSearchMindKey |
... | ... |
響應事件
本組件在設計的時候,實際只提供了兩個回調接口:搜索和返回。如果開發者需要響應一些其它事件,可以參考組件js的導出接口,如下所示。
// 導出接口 module.exports = { init: init, //初始化函數 wxSearchInput: wxSearchInput,// 輸入變化時的操作 wxSearchKeyTap: wxSearchKeyTap, // 點擊提示或者關鍵字、歷史記錄時的操作 wxSearchDeleteAll: wxSearchDeleteAll, // 刪除所有的歷史記錄 wxSearchConfirm: wxSearchConfirm, // 搜索函數 wxSearchClear: wxSearchClear, // 清空函數 }
可以看到的是,為了減少開發者的開發量,這些事件在QuickStart中聲明成固定部分。如果開發者需要添加自己的事件,可以修改那些固定的部分,提供自己的響應函數,並在自己的函數中調用WxSearch.wxSearchXXX
函數,從而保證搜索框的正確效果。
3、在項目中正式使用
首先復制wxSearchView包到項目,與pages同級,
然后先在videoInfo.js頁面定義showSearch搜索事件。
接着按照步驟走下去
// 1 導入js文件 var WxSearch = require('../../wxSearchView/wxSearchView.js'); Page({ data: { }, onLoad: function () { // 2 搜索欄初始化 var that = this; WxSearch.init( that, // 本頁面一個引用 ['慕課網', 'imooc', "java", "小程序", 'zookeeper', 'springboot'], // 熱點搜索推薦,[]表示不使用 [],// 搜索匹配,[]表示不使用 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=返回' }) } })
五、 修改全局用戶對象使用緩存
然后在相應的文件上修改。
六、查詢接口完善以及熱搜詞保存
七、熱搜詞查詢接口開發
八、熱搜詞前后端聯調
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, // ['慕課網', 'imooc', "java", "小程序", 'zookeeper', 'springboot'], // 熱點搜索推薦,[]表示不使用 hotList,// 搜索匹配,[]表示不使用 that.mySearchFunction, // 提供一個搜索回調函數 that.myGobackFunction //提供一個返回回調函數 ); } }) },
九、搜索功能整合首頁列表聯調
先定義搜索回調事件
會帶上參數跳轉到index.js上,
//index.js //獲取應用實例 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.showToast({ 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); 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); } })
十、熱搜查詢聯調與視頻對象的播放與暫停