uniapp实现聊天|uniapp聊天源码
生活随笔
收集整理的這篇文章主要介紹了
uniapp实现聊天|uniapp聊天源码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
泡泡IM uniapp版聊天源碼是一套完整的基于uniapp開發的聊天軟件源碼,可編譯成微信小程序、安卓 IOS APP聊天軟件、H5網頁聊天室。uniapp聊天源碼未加密,無外部依賴,可私有化部署,可二次開發。文檔全面,接口豐富,方便二次開發或者對接現有項目。
聊天軟件主要通能
1、支持發語音、文字、圖片、表情、錄制視頻
2、支持私聊、群聊
3、群聊支持建群、退群、解散群組、禁言、踢人、拉人進群、群備注等功能、管理員
4、個人信息支持更改昵稱、頭像、個性簽名等
5、支持查看歷史消息、離線消息
6、支持好友查找、好友申請、同意好友申請、拒絕申請、刪除好友,好友備注
7、支持消息撤回,臟字過濾
8、支持通訊錄,按字母順序排列
9、離線消息欄推送能力
10、管理后臺
聊天源碼技術棧:
編輯器:HBuilderX
技術框架:uni-app + vue
后端:PHP 語言, ThinkPHP框架
即時通訊:WebSocket workerman
數據庫:MySQL
Web服務器:Nginx 或 Apache
代碼片段:
body {background-color: #f1f1f1;font-size: 28rpx;color: #333333;font-family: Helvetica Neue, Helvetica, sans-serif;overflow: hidden; }view, scroll-view, swiper, button, input, textarea, label, navigator, image {box-sizing: border-box; }.round {border-radius: 5000rpx; }.radius {border-radius: 6rpx; }/* ==================圖片==================== */image {max-width: 100%;display: inline-block;position: relative;z-index: 0; }image.loading::before {content: "";background-color: #f5f5f5;display: block;position: absolute;width: 100%;height: 100%;z-index: -2; }image.loading::after {content: "\e7f1";font-family: "cuIcon";position: absolute;top: 0;left: 0;width: 32rpx;height: 32rpx;line-height: 32rpx;right: 0;bottom: 0;z-index: -1;font-size: 32rpx;margin: auto;color: #ccc;-webkit-animation: cuIcon-spin 2s infinite linear;animation: cuIcon-spin 2s infinite linear;display: block; }.response {width: 100%; }/* ==================開關==================== */switch, checkbox, radio {position: relative; }switch::after, switch::before {font-family: "cuIcon";content: "\e645";position: absolute;color: #ffffff !important;top: 0%;left: 0rpx;font-size: 26rpx;line-height: 26px;width: 50%;text-align: center;pointer-events: none;transform: scale(0, 0);transition: all 0.3s ease-in-out 0s;z-index: 9;bottom: 0;height: 26px;margin: auto; }switch::before {content: "\e646";right: 0;transform: scale(1, 1);left: auto; }switch[checked]::after, switch.checked::after {transform: scale(1, 1); }switch[checked]::before, switch.checked::before {transform: scale(0, 0); }/* #ifndef MP-ALIPAY */ radio::before, checkbox::before {font-family: "cuIcon";content: "\e645";position: absolute;color: #ffffff !important;top: 50%;margin-top: -8px;right: 5px;font-size: 32rpx;line-height: 16px;pointer-events: none;transform: scale(1, 1);transition: all 0.3s ease-in-out 0s;z-index: 9; }radio .wx-radio-input, checkbox .wx-checkbox-input, radio .uni-radio-input, checkbox .uni-checkbox-input {margin: 0;width: 24px;height: 24px; }checkbox.round .wx-checkbox-input, checkbox.round .uni-checkbox-input {border-radius: 100rpx; }/* #endif */ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Recorder = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ "use strict";module.exports = require("./recorder").Recorder;},{"./recorder":2}],2:[function(require,module,exports){ 'use strict';var _createClass = (function () {function defineProperties(target, props) {for (var i = 0; i < props.length; i++) {var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);}}return function (Constructor, protoProps, staticProps) {if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;}; })();Object.defineProperty(exports, "__esModule", {value: true }); exports.Recorder = undefined;var _inlineWorker = require('inline-worker');var _inlineWorker2 = _interopRequireDefault(_inlineWorker);function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj }; }function _classCallCheck(instance, Constructor) {if (!(instance instanceof Constructor)) {throw new TypeError("Cannot call a class as a function");} }var Recorder = exports.Recorder = (function () {function Recorder(source, cfg) {var _this = this;_classCallCheck(this, Recorder);this.config = {bufferLen: 4096,numChannels: 2,mimeType: 'audio/wav'};this.recording = false;this.callbacks = {getBuffer: [],exportWAV: []};Object.assign(this.config, cfg);this.context = source.context;this.node = (this.context.createScriptProcessor || this.context.createJavaScriptNode).call(this.context, this.config.bufferLen, this.config.numChannels, this.config.numChannels);this.node.onaudioprocess = function (e) {if (!_this.recording) return;var buffer = [];for (var channel = 0; channel < _this.config.numChannels; channel++) {buffer.push(e.inputBuffer.getChannelData(channel));}_this.worker.postMessage({command: 'record',buffer: buffer});};source.connect(this.node);this.node.connect(this.context.destination); //this should not be necessaryvar self = {};this.worker = new _inlineWorker2.default(function () {var recLength = 0,recBuffers = [],sampleRate = undefined,numChannels = undefined;self.onmessage = function (e) {switch (e.data.command) {case 'init':init(e.data.config);break;case 'record':record(e.data.buffer);break;case 'exportWAV':exportWAV(e.data.type);break;case 'getBuffer':getBuffer();break;case 'clear':clear();break;}};function init(config) {sampleRate = config.sampleRate;numChannels = config.numChannels;initBuffers();}function record(inputBuffer) {for (var channel = 0; channel < numChannels; channel++) {recBuffers[channel].push(inputBuffer[channel]);}recLength += inputBuffer[0].length;}function exportWAV(type) {var buffers = [];for (var channel = 0; channel < numChannels; channel++) {buffers.push(mergeBuffers(recBuffers[channel], recLength));}var interleaved = undefined;if (numChannels === 2) {interleaved = interleave(buffers[0], buffers[1]);} else {interleaved = buffers[0];}var dataview = encodeWAV(interleaved);var audioBlob = new Blob([dataview], { type: type });self.postMessage({ command: 'exportWAV', data: audioBlob });}function getBuffer() {var buffers = [];for (var channel = 0; channel < numChannels; channel++) {buffers.push(mergeBuffers(recBuffers[channel], recLength));}self.postMessage({ command: 'getBuffer', data: buffers });}function clear() {recLength = 0;recBuffers = [];initBuffers();}function initBuffers() {for (var channel = 0; channel < numChannels; channel++) {recBuffers[channel] = [];}}function mergeBuffers(recBuffers, recLength) {var result = new Float32Array(recLength);var offset = 0;for (var i = 0; i < recBuffers.length; i++) {result.set(recBuffers[i], offset);offset += recBuffers[i].length;}return result;}function interleave(inputL, inputR) {var length = inputL.length + inputR.length;var result = new Float32Array(length);var index = 0,inputIndex = 0;while (index < length) {result[index++] = inputL[inputIndex];result[index++] = inputR[inputIndex];inputIndex++;}return result;}function floatTo16BitPCM(output, offset, input) {for (var i = 0; i < input.length; i++, offset += 2) {var s = Math.max(-1, Math.min(1, input[i]));output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);}}function writeString(view, offset, string) {for (var i = 0; i < string.length; i++) {view.setUint8(offset + i, string.charCodeAt(i));}}function encodeWAV(samples) {var buffer = new ArrayBuffer(44 + samples.length * 2);var view = new DataView(buffer);/* RIFF identifier */writeString(view, 0, 'RIFF');/* RIFF chunk length */view.setUint32(4, 36 + samples.length * 2, true);/* RIFF type */writeString(view, 8, 'WAVE');/* format chunk identifier */writeString(view, 12, 'fmt ');/* format chunk length */view.setUint32(16, 16, true);/* sample format (raw) */view.setUint16(20, 1, true);/* channel count */view.setUint16(22, numChannels, true);/* sample rate */view.setUint32(24, sampleRate, true);/* byte rate (sample rate * block align) */view.setUint32(28, sampleRate * 4, true);/* block align (channel count * bytes per sample) */view.setUint16(32, numChannels * 2, true);/* bits per sample */view.setUint16(34, 16, true);/* data chunk identifier */writeString(view, 36, 'data');/* data chunk length */view.setUint32(40, samples.length * 2, true);floatTo16BitPCM(view, 44, samples);return view;}}, self);this.worker.postMessage({command: 'init',config: {sampleRate: this.context.sampleRate,numChannels: this.config.numChannels}});this.worker.onmessage = function (e) {var cb = _this.callbacks[e.data.command].pop();if (typeof cb == 'function') {cb(e.data.data);}};}_createClass(Recorder, [{key: 'record',value: function record() {this.recording = true;}}, {key: 'stop',value: function stop() {this.recording = false;}}, {key: 'clear',value: function clear() {this.worker.postMessage({ command: 'clear' });}}, {key: 'getBuffer',value: function getBuffer(cb) {cb = cb || this.config.callback;if (!cb) throw new Error('Callback not set');this.callbacks.getBuffer.push(cb);this.worker.postMessage({ command: 'getBuffer' });}}, {key: 'exportWAV',value: function exportWAV(cb, mimeType) {mimeType = mimeType || this.config.mimeType;cb = cb || this.config.callback;if (!cb) throw new Error('Callback not set');this.callbacks.exportWAV.push(cb);this.worker.postMessage({command: 'exportWAV',type: mimeType});}}], [{key: 'forceDownload',value: function forceDownload(blob, filename) {var url = (window.URL || window.webkitURL).createObjectURL(blob);var link = window.document.createElement('a');link.href = url;link.download = filename || 'output.wav';var click = document.createEvent("Event");click.initEvent("click", true, true);link.dispatchEvent(click);}}]);return Recorder; })();exports.default = Recorder;},{"inline-worker":3}],3:[function(require,module,exports){ "use strict";module.exports = require("./inline-worker"); },{"./inline-worker":4}],4:[function(require,module,exports){ (function (global){ "use strict";var _createClass = (function () { function defineProperties(target, props) { for (var key in props) { var prop = props[key]; prop.configurable = true; if (prop.value) prop.writable = true; } Object.defineProperties(target, props); } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };var WORKER_ENABLED = !!(global === global.window && global.URL && global.Blob && global.Worker);var InlineWorker = (function () { function InlineWorker(func, self) {var _this = this;_classCallCheck(this, InlineWorker);if (WORKER_ENABLED) {var functionBody = func.toString().trim().match(/^function\s*\w*\s*\([\w\s,]*\)\s*{([\w\W]*?)}$/)[1];var url = global.URL.createObjectURL(new global.Blob([functionBody], { type: "text/javascript" }));return new global.Worker(url);}this.self = self;this.self.postMessage = function (data) {setTimeout(function () {_this.onmessage({ data: data });}, 0);};setTimeout(function () {func.call(self);}, 0); }_createClass(InlineWorker, {postMessage: {value: function postMessage(data) {var _this = this;setTimeout(function () {_this.self.onmessage({ data: data });}, 0);}} });return InlineWorker; })();module.exports = InlineWorker; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}]},{},[1])(1) });uniapp聊天效果預覽
轉自 https://www.popoim.com/im/article/9
總結
以上是生活随笔為你收集整理的uniapp实现聊天|uniapp聊天源码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何搭建“业务化”的指标体系?
- 下一篇: 治疗开发拖延症-任务拆分和执行