摘要:仿抖音短視頻小程序開發(fā)一項(xiàng)目的簡(jiǎn)介仿抖音短視頻小程序開發(fā)二項(xiàng)目功能分析與具體實(shí)現(xiàn)源代碼仿抖音短視頻小程序開發(fā)全棧式實(shí)戰(zhàn)項(xiàng)目短視頻后臺(tái)管理系統(tǒng)小程序的后臺(tái)管理系統(tǒng)涉及的技術(shù)棧框架一用戶列表的獲取與分頁前端代碼用戶列表展示的表格底部
SpringBoot 仿抖音短視頻小程序開發(fā)(一):項(xiàng)目的簡(jiǎn)介(https://segmentfault.com/a/11...小程序的后臺(tái)管理系統(tǒng)
SpringBoot 仿抖音短視頻小程序開發(fā)(二):項(xiàng)目功能分析與具體實(shí)現(xiàn)(https://segmentfault.com/a/11...
源代碼: SpringBoot 仿抖音短視頻小程序開發(fā) 全棧式實(shí)戰(zhàn)項(xiàng)目(https://gitee.com/scau_zns/sh...)
短視頻后臺(tái)管理系統(tǒng):(https://gitee.com/scau_zns/sh...
涉及的技術(shù)棧:Bootstrap + jQuery + jGrid + SSM框架 + zookeeper
一、用戶列表的獲取與分頁前端代碼:
jGrid發(fā)送請(qǐng)求獲取數(shù)據(jù)封裝好展示到頁面
// 用戶列表 var handleList = function() { // 上下文對(duì)象路徑 var hdnContextPath = $("#hdnContextPath").val(); var apiServer = $("#apiServer").val(); var jqGrid = $("#usersList"); jqGrid.jqGrid({ caption: "短視頻用戶列表", url: hdnContextPath + "/users/list.action", mtype: "post", styleUI: "Bootstrap",//設(shè)置jqgrid的全局樣式為bootstrap樣式 datatype: "json", colNames: ["ID", "頭像", "用戶名", "昵稱", "粉絲數(shù)", "關(guān)注數(shù)", "獲贊數(shù)"], colModel: [ { name: "id", index: "id", width: 30, sortable: false, hidden: false }, { name: "faceImage", index: "username", width: 50, sortable: false, formatter:function(cellvalue, options, rowObject) { var src = apiServer + cellvalue; var img = "
使用jGrid發(fā)送請(qǐng)求給后臺(tái)
// 條件查詢所有用戶列表 $("#searchUserListButton").click(function(){ var searchUsersListForm = $("#searchUserListForm"); jqGrid.jqGrid().setGridParam({ page: 1, url: hdnContextPath + "/users/list.action?" + searchUsersListForm.serialize(), }).trigger("reloadGrid"); });二、背景音樂BGM的上傳、查詢和刪除 上傳
$("#file").fileupload({ pasteZone: "#bgmContent", dataType: "json", done: function(e, data) { console.log(data); if (data.result.status != "200") { alert("長(zhǎng)傳失敗..."); } else { var bgmServer = $("#bgmServer").val(); var url = bgmServer + data.result.data; $("#bgmContent").html("點(diǎn)我播放"); $("#path").attr("value", data.result.data); } } });
后臺(tái)接口保存BGM的方法參考上傳頭像的方法
分頁查詢參考用戶列表信息的分頁查詢多少
刪除BGMvar deleteBgm = function(bgmId) { var flag = window.confirm("是否確認(rèn)刪除???"); if (!flag) { return; } $.ajax({ url: $("#hdnContextPath").val() + "/video/delBgm.action?bgmId=" + bgmId, type: "POST", success: function(data) { if (data.status == 200 && data.msg == "OK") { alert("刪除成功~~"); var jqGrid = $("#bgmList"); jqGrid.jqGrid().trigger("reloadGrid"); } } }) }三、舉報(bào)管理 禁止播放
var forbidVideo = function(videoId) { var flag = window.confirm("是否禁播"); if (!flag) { return; } $.ajax({ url: $("#hdnContextPath").val() + "/video/forbidVideo.action?videoId=" + videoId, type: "POST", async: false, success: function(data) { if(data.status == 200 && data.msg == "OK") { alert("操作成功"); var jqGrid = $("#usersReportsList"); //reloadGrid是重新加載表格 jqGrid.jqGrid().trigger("reloadGrid"); } else { console.log(JSON.stringify(data)); } } }) }四、后臺(tái)管理系統(tǒng)增加或刪除BGM,向zookeeper-server創(chuàng)建子節(jié)點(diǎn),讓小程序后端監(jiān)聽【重點(diǎn)】 1、首先安裝Zookeeper到Linux上,啟動(dòng)服務(wù)器 2、編寫zk客戶端代碼:
import org.apache.curator.framework.CuratorFramework; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.ZooDefs.Ids; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ZKCurator { //zk客戶端 private CuratorFramework client = null; final static Logger log = LoggerFactory.getLogger(ZKCurator.class); public ZKCurator(CuratorFramework client) { this.client = client; } public void init() { client = client.usingNamespace("admin"); try { //判斷在admin命名空間下是否有bgm節(jié)點(diǎn) /admin/bgm if( client.checkExists().forPath("/bgm") == null ) { //對(duì)于zk來講,有兩種類型的節(jié)點(diǎn),一種是持久節(jié)點(diǎn)(永久存在,除非手動(dòng)刪除),另一種是臨時(shí)節(jié)點(diǎn)(會(huì)話斷開,自動(dòng)刪除) client.create().creatingParentContainersIfNeeded() .withMode(CreateMode.PERSISTENT) //持久節(jié)點(diǎn) .withACL(Ids.OPEN_ACL_UNSAFE) //匿名權(quán)限 .forPath("/bgm"); log.info("zookeeper客戶端連接初始化成功"); log.info("zookeeper服務(wù)端狀態(tài):{}",client.isStarted()); } } catch (Exception e) { log.error("zookeeper客戶端連接初始化失敗"); e.printStackTrace(); } } /** * 增加或者刪除Bgm,向zk-server創(chuàng)建子節(jié)點(diǎn),供小程序后端監(jiān)聽 * @param bgmId * @param operType */ public void sendBgmOperator(String bgmId, String operObject) { try { client.create().creatingParentContainersIfNeeded() .withMode(CreateMode.PERSISTENT) //持久節(jié)點(diǎn) .withACL(Ids.OPEN_ACL_UNSAFE) //匿名權(quán)限 .forPath("/bgm/" + bgmId, operObject.getBytes()); } catch (Exception e) { e.printStackTrace(); } } }3、在applicationContext-zookeeper.xml配置zookeeper:
4、上傳或者刪除BGM時(shí)調(diào)用VideoServiceImpl.java的方法
@Autowired private ZKCurator zKCurator; @Override public void addBgm(Bgm bgm) { String id = sid.nextShort(); bgm.setId(id); bgmMapper.insert(bgm); Map5、小程序編寫代碼監(jiān)聽zookeeper的節(jié)點(diǎn),并對(duì)其做出相應(yīng)的刪除和上傳操作【重點(diǎn)】map = new HashMap<>(); map.put("operType", BGMOperatorTypeEnum.ADD.type); map.put("path", bgm.getPath()); zKCurator.sendBgmOperator(id, JSONUtils.toJSONString(map)); } @Override public void deleteBgm(String id) { Bgm bgm = bgmMapper.selectByPrimaryKey(id); bgmMapper.deleteByPrimaryKey(id); Map map = new HashMap<>(); map.put("operType", BGMOperatorTypeEnum.DELETE.type); map.put("path", bgm.getPath()); zKCurator.sendBgmOperator(id, JSONUtils.toJSONString(map)); }
初始化zookeeper客戶端
private CuratorFramework client = null; final static Logger log = LoggerFactory.getLogger(ZKCuratorClient.class); // public static final String ZOOKEEPER_SERVER = "120.79.18.36:2181"; public void init() { if(client != null) { return; } //重試策略 RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5); //創(chuàng)建zk客戶端 120.79.18.36:2181 client = CuratorFrameworkFactory.builder().connectString(resourceConfig.getZookeeperServer()).sessionTimeoutMs(10000) .retryPolicy(retryPolicy).namespace("admin").build(); //啟動(dòng)客戶端 client.start(); try { addChildWatch("/bgm"); } catch (Exception e) { e.printStackTrace(); } }
監(jiān)聽zk-server的節(jié)點(diǎn),當(dāng)短視頻后臺(tái)管理系統(tǒng)上傳或者刪除某個(gè)BGM的時(shí)候,小程序后臺(tái)服務(wù)器通過Zookeeper監(jiān)聽自動(dòng)下載背景音樂
public void addChildWatch(String nodePath) throws Exception { final PathChildrenCache cache = new PathChildrenCache(client, nodePath, true); cache.start(); cache.getListenable().addListener(new PathChildrenCacheListener() { @Override public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception { if(event.getType().equals(PathChildrenCacheEvent.Type.CHILD_ADDED)){ log.info("監(jiān)聽到事件CHILD_ADDED"); //1. 從數(shù)據(jù)庫查詢bgm對(duì)象,獲取路徑Path String path = event.getData().getPath(); String operatorObjStr = new String(event.getData().getData()); Mapmap = JsonUtils.jsonToPojo(operatorObjStr, Map.class); String operatorType = map.get("operType"); String songPath = map.get("path"); // String[] arr = path.split("/"); // String bgmId = arr[arr.length-1]; // Bgm bgm = bgmService.queryBgmById(bgmId); // if(bgm == null){ // return; // } //1.1 bgm所在的相對(duì)路徑 // String songPath = bgm.getPath(); //2. 定義保存到本地的bgm路徑 // String filePath = "E:imooc_videos_dev" + songPath; String filePath = resourceConfig.getFileSpace() + songPath; //3. 定義下載的路徑(播放url) String[] arrPath = songPath.split(""); //windows // String[] arrPath = songPath.split("/"); //linux String finalPath = ""; //3.1 處理url的斜杠以及編碼 for(int i=0; i
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/77553.html
摘要:一項(xiàng)目簡(jiǎn)介模仿抖音做的一個(gè)短視頻微信小程序,用搭建小程序后臺(tái),用框架搭建短視頻后臺(tái)管理系統(tǒng),小程序后臺(tái)通過分布式監(jiān)聽節(jié)點(diǎn)自動(dòng)下載或刪除短視頻后臺(tái)管理系統(tǒng)上傳的視頻。 一、項(xiàng)目簡(jiǎn)介 模仿抖音做的一個(gè)短視頻微信小程序,用SpringBoot搭建小程序后臺(tái),用SSM框架搭建短視頻后臺(tái)管理系統(tǒng),小程序后臺(tái)通過分布式zookeeper監(jiān)聽節(jié)點(diǎn)自動(dòng)下載或刪除短視頻后臺(tái)管理系統(tǒng)上傳的視頻。 二、環(huán)境...
閱讀 752·2021-09-28 09:35
閱讀 2591·2019-08-29 11:25
閱讀 2154·2019-08-23 18:36
閱讀 1849·2019-08-23 16:31
閱讀 2065·2019-08-23 14:50
閱讀 3112·2019-08-23 13:55
閱讀 3286·2019-08-23 12:49
閱讀 2074·2019-08-23 11:46