融云开发

融云开发

融云 Web 播放声音 — Flash 篇 (播放 AMR、WAV)

WebRTC赵炳东 发表了文章 • 0 个评论 • 243 次浏览 • 2021-01-05 11:50 • 来自相关话题

本文主要介绍 Flash 播放 AMR 格式 Base64码 音频。在此之前么有接触过 Flash ,接触 AS3 是一头雾水,不过幸好有 TypeScript 和 JavaScript 的基础看起来不是很费劲,现学现卖的就是开了 ”跳坑“ 之旅~~~1、实现... ...查看全部

本文主要介绍 Flash 播放 AMR 格式 Base64码 音频。

在此之前么有接触过 Flash ,接触 AS3 是一头雾水,不过幸好有 TypeScript 和 JavaScript 的基础看起来不是很费劲,现学现卖的就是开了 ”跳坑“ 之旅~~~

1、实现思路

起初一点实现思路都木有,不知道该从何做起,只知道用 Flash 播放 AMR ,度娘谷姐的一顿找,结果可想而知,没有糟糕,只有十分糟糕,哈哈。

后来想了想,凡事都得有个思路,不能闷头干,瞬间恍然大悟,为自己浪费的快一天的时间,感到羞愧和害怕…..

① Flash 都能播放哪些音频。

② 在 ActionScript 中AMR 是如何转换成 Flash 可播放的音频的。

③ JS 中如何调用 ActionScript 中方法,如何交互。

④ 如何把 SWF 文件嵌入到 HTML 页面中。

⑤ 如何把 AMR(Audio) 和 Flash 播放AMR 两种方式封装起来。

2、逐一破解

① Flash 都能播放哪些音频:

MP3 格式是 Flash 默认支持的音频格式,WAVE 格式需要转换可以播放,其他格式也是需要转换的,因为先做的 Chrome 下播放声音,对 WAVE 音频多少有些了解,所以决定从 WAVE 音频入手,所以按照上述的套路来 ”屡思路“:

(1) 不管如何转换,肯定要操作字节数组,所以第一步把 AMR 格式的 base64 码 转换为 ByteArray 数组。

(2) 如何把 AMR 的 ByteArray 转换成 WAVE 格式的 ByteArray 数组,毫无疑问 ,肯定需要解码的过程。

按照这两个小步骤逐一做,很快找到了 base64 的转码过程(开始是自己用 AS 实现了 JS 中的的 转码过程,可用但不完美,最终借鉴 github 上大牛的转换过程),但 AMR 转换 WAVE 这个就没有那么容易了,最终确定,AS 解 AMR 比较费劲,需要 用 C 语言来解码,然后用 CrossBirdge 生成可以供 Flash 调用的 SWC 文件。

OK,到这为止,第一步就完美解决了。

② 在 ActionScript 中AMR 是如何转换成 Flash 可播放的音频的:

    上文中有提到,需要用 C 语言 进行对 AMR 解码,下文中会给出 C 语言解码和生成 SWC 的教程(借鉴大牛的)。

③ JS 中如何调用 ActionScript 中方法,如何交互,下文中会贴出完整代码(一定要看注释、注释、注释),此处写出 JS 调用过程。

JS 代码:

function callFlashMethod() {
  // play 是 flash 代码中定义的 ExternalInterface.addCallback("play",this.play); 下文中会有详细介绍。
  thisMovie("嵌入页面上<object>的ID").play("base64str");
}
function thisMovie(movieName) {
    if (navigator.appName.indexOf("Microsoft") != -1) {
        return window[movieName]
    }
    else {
        return document[movieName]
    }
}
document.getElementById("playId").onclick = function(){
    callFlashMethod();
};

④ 如何把 SWF 文件嵌入到 HTML 页面中:

使用 swfobject.js 可以将 swf 文件嵌入到 HTML 页面中,参考资料 :http://www.cnblogs.com/Carpe-Diem/articles/2310831.html

⑤ 如何把 AMR(Audio) 和 Flash 播放AMR 两种方式封装起来:

有了上面的铺垫,轻而易举的就可以封装啦(主要看 isIE 为 true 的情况):

var RongIMLib;
(function (RongIMLib) {
    var RongIMVoice = (function () {
        function RongIMVoice() {
        }
        /**
        * 初始化声音库
        */
        RongIMVoice.init = function () {
            if (this.isIE) {
                var div = document.createElement("div");
                div.setAttribute("id", "flashContent");
                document.body.appendChild(div);
                var script = document.createElement("script");
                script.src = "http://cdn.ronghub.com/swfobject-2.0.0.min.js";
                var header = document.getElementsByTagName("head")[0];
                header.appendChild(script);
                setTimeout(function () {
                    var swfVersionStr = "11.4.0";
                    var flashvars = {};
                    var params = {};
                    params.quality = "high";
                    params.bgcolor = "#ffffff";
                    params.allowScriptAccess = "always";
                    params.allowfullscreen = "true";
                    var attributes = {};
                    attributes.id = "player";
                    attributes.name = "player";
                    attributes.align = "middle";
                    swfobject.embedSWF("http://cdn.ronghub.com/player-2.0.2.swf", "flashContent", "1", "1", swfVersionStr, null, flashvars, params, attributes);
                }, 200);
            }
            else {
                var list = ["http://cdn.ronghub.com/pcmdata-2.0.0.min.js", "http://cdn.ronghub.com/libamr-2.0.1.min.js"];
                for (var i = 0, len = list.length; i < len; i++) {
                    var script = document.createElement("script");
                    script.src = list[i];
                    document.head.appendChild(script);
                }
            }
            this.isInit = true;
        };
        /**
        * 开始播放声音
        * @param data {string} amr 格式的 base64 码
        * @param duration {number} 播放大概时长 用 data.length / 1024
        */
        RongIMVoice.play = function (data, duration) {
            this.checkInit("play");
            var me = this;
            if (me.isIE) {
                me.thisMovie().doAction("init", data);
            }
            else {
                me.palyVoice(data);
                me.onCompleted(duration);
            }
        };
        /**
        * 停止播放声音
        */
        RongIMVoice.stop = function () {
            this.checkInit("stop");
            var me = this;
            if (me.isIE) {
                me.thisMovie().doAction("stop");
            }
            else {
                if (me.element) {
                    me.element.stop();
                }
            }
        };
        /**
        * 播放声音时调用的方法
        */
        RongIMVoice.onprogress = function () {
            this.checkInit("onprogress");
        };
        RongIMVoice.checkInit = function (postion) {
            if (!this.isInit) {
                throw new Error("RongIMVoice not initialized,postion:" + postion);
            }
        };
        RongIMVoice.thisMovie = function () {
            return eval("window['player']");
        };
        RongIMVoice.onCompleted = function (duration) {
            var me = this;
            var count = 0;
            var timer = setInterval(function () {
                count++;
                me.onprogress();
                if (count >= duration) {
                    clearInterval(timer);
                }
            }, 1000);
            if (me.isIE) {
                me.thisMovie().doAction("play");
            }
        };
        RongIMVoice.base64ToBlob = function (base64Data, type) {
            var mimeType;
            if (type) {
                mimeType = { type: type };
            }
            base64Data = base64Data.replace(/^(.*)[,]/, '');
            var sliceSize = 1024;
            var byteCharacters = atob(base64Data);
            var bytesLength = byteCharacters.length;
            var slicesCount = Math.ceil(bytesLength / sliceSize);
            var byteArrays = new Array(slicesCount);
            for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
                var begin = sliceIndex * sliceSize;
                var end = Math.min(begin + sliceSize, bytesLength);
                var bytes = new Array(end - begin);
                for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
                    bytes[i] = byteCharacters[offset].charCodeAt(0);
                }
                byteArrays[sliceIndex] = new Uint8Array(bytes);
            }
            return new Blob(byteArrays, mimeType);
        };
        RongIMVoice.palyVoice = function (base64Data) {
            var reader = new FileReader(), blob = this.base64ToBlob(base64Data, "audio/amr"), me = this;
            reader.onload = function () {
                var samples = new AMR({
                    benchmark: true
                }).decode(reader.result);
                me.element = AMR.util.play(samples);
            };
            reader.readAsBinaryString(blob);
        };
        RongIMVoice.isIE = /Trident/.test(navigator.userAgent);
        RongIMVoice.isInit = false;
        return RongIMVoice;
    })();
    RongIMLib.RongIMVoice = RongIMVoice;
    //兼容AMD CMD
    if ("function" === typeof require && "object" === typeof module && module && module.id && "object" === typeof exports && exports) {
        module.exports = RongIMVoice;
    }
    else if ("function" === typeof define && define.amd) {
        define("RongIMVoice", [], function () {
            return RongIMVoice;
        });
    }
})(RongIMLib || (RongIMLib = {}));

 

截止到这里,Flash 播放 AMR 格式 base64 码 就说完了,主要是介绍下大概思路

以上是融云 SDK 里的源码,不过最近推出了直接使用 Audio 方式播放 AAC 格式的音频文件

原始文章连接:https://www.cnblogs.com/yuhongda0315/p/5224450.html

融云官网:https://www.rongcloud.cn

融云文档:https://docs.rongcloud.cn/v4


Web 端使用融云 SDK 集成实现滑动加载历史消息

IM即时通讯苏道 发表了文章 • 0 个评论 • 302 次浏览 • 2020-12-16 17:05 • 来自相关话题

刚接触即时通讯的项目,在使用融云的 SDK 来完成项目需求时,磕磕碰碰,死命看文档和提工单问融云的技术人员,真是一段痛并快乐的历程,哈哈哈!今天分享一个滑动加载获取历史消息的功能知识点先看获取历史消息的代码:var conversation ... ...查看全部

刚接触即时通讯的项目,在使用融云的 SDK 来完成项目需求时,磕磕碰碰,死命看文档和提工单问融云的技术人员,真是一段痛并快乐的历程,哈哈哈!今天分享一个滑动加载获取历史消息的功能

微信截图_20201216165629.png

知识点

先看获取历史消息的代码:

var conversation = im.Conversation.get({
  targetId: '接收方的 userId',
  type: RongIMLib.CONVERSATION_TYPE.PRIVATE
});
var option = {
  timestrap: +new Date(),
  count: 20
};
conversation.getMessages(option).then(function(result){
  var list = result.list; // 历史消息列表
  var hasMore = result.hasMore; // 是否还有历史消息可以获取
  console.log('获取历史消息成功', list, hasMore);
});

参数说明:
image

1、因为 Web 端没有本地存储,不提供本地获取方法,只能从远端获取
2、使用获取历史消息方法需要在开发者后台开启 IM 商用版 - 单群聊云存储 服务
3、每次最多只能获取 20 条历史消息
所以问题来了,获取历史消息的方法最多只能获取 20 条消息,那我想获取 20 条之前的消息,怎么办呢?
我们需要从它的参数来入手,解决思路就是改变参数 timestrap (时间戳),在每次调用 conversation.getMessages 成功获得历史消息列表 result.list 后,将 result.list 中 sentTime 值最小的赋值给 timestrap 然后滑动继续调用 conversation.getMessages 即可获取不同时间段的历史消息,也可以通过改变参数 order 来改变是获取该时间段之前的消息还是之后的消息。

是不是很简单,反正一开始我是迷糊了,所以记录一下,也分享给有需要的同学,不足的地方还请留言指正,大家共勉 ~ 加油!!!

下图是 result.list 中 message 的属性说明:

image



融云IM SDK web 端集成 — 表情采坑篇

IM即时通讯苏道 发表了文章 • 0 个评论 • 325 次浏览 • 2020-12-16 17:05 • 来自相关话题

公司集成 IM 使用的是融云的 IM SDK,我们有移动端,有 web 端,移动端同事集成表情时还是蛮顺利的貌似移动端 SDK 里就支持,一切都很顺理成章的样子,web 端就有些棘手了。web 端的表情是需要单独引入插件的,这点还是有点困惑的。一脸懵的看着文档... ...查看全部

公司集成 IM 使用的是融云的 IM SDK,我们有移动端,有 web 端,移动端同事集成表情时还是蛮顺利的貌似移动端 SDK 里就支持,一切都很顺理成章的样子,web 端就有些棘手了。web 端的表情是需要单独引入插件的,这点还是有点困惑的。

微信截图_20201216165823.png

一脸懵的看着文档,踩着优雅的脚步入坑,完成我的表情集成采坑之旅

这第一步不用说肯定是 SDK 的初始化和连接了。这些在文档的指引下都是很顺利的还很欣慰,还为文档的细致点过赞。

这第二步就是细化相关功能了。比如说发消息时可以带表情。

手动划重点专用~

按照文档https://docs.rongcloud.cn/v4/views/im/noui/guide/private/msgmanage/msgsend/web.html#emoji中的示例发了一条表情消息,完美成功了。看到文档中有 Emoji 插件,好奇的点开看看。好吧 ╮(╯▽╰)╭,如果要发表情消息需要集成插件。

没关系,没关系,一个插件而已。有文档有教程不怕不拍的 (^▽^)


开心的看着文档,优雅的写着代码~~

按步骤集成,自认为本人是个比较听话的,文档让咱干嘛就干嘛。决不搞特殊。

so ~ 一切都很完美很太平。开心的集成,拿到了了表,发消息也可以正常携带了,美美的给了移动端,你看成功了 ~

哈哈哈暗自窃喜中 ヾ( ̄ー ̄)X(^▽^)ゞ 奈何移动端同事也同样会给了我一份大礼给 web 发了个带表情的消息。点开一看。这什么。。。这什么。。。这一堆黑框是什么鬼 -_-||

额 ~ 我做错了什么。。。检查了变没问题啊,看了眼数据心里安慰了许多,原来收到的就是那么个黑框,于是理直气壮的去融云提了工单。


工单问答时间:

问:web 端收到的表情展示成方块

答:
1、web 端展示 emoji 时, 不管是通过历史消息还是消息监听器监听的消息, 都需要调用 emojiToHTML 转成 HTML 或者使用 symbolToEmoji 将 unicode(您说的小方块) 转化成原生 emoji 字符
2、不同浏览器, 不同设备, 展示的原生 Emoji 表情都不同
3、如需多端展示 Emoji 一致, 需使用 emojiToHTML 转化为 HTML 后再展示(此方法为以图片形式展示)

按照工单的提示对消息内容做了处理,调用了 emojiToHTML 方法。完美解决。


废话少说,上代码:

emojiToHtml:function(message){
  return RongIMLib.RongIMEmoji.emojiToHTML(message);
},
<pre class="Message-entry" v-html="emojiToHtml(message.content)">

由于开发使用了 vue 所以直接在标签上做了处理,在需要转换的消息类型上调用此方法即可。目前本人仅仅转换了文本类消息。

参考文案:

文档地址:https://docs.rongcloud.cn/v4/views/im/noui/guide/private/msgmanage/msgsend/web.html#emoji

融云官网:https://www.rongcloud.cn/


融云 Web 播放声音 — Flash 篇 (播放 AMR、WAV)

WebRTC赵炳东 发表了文章 • 0 个评论 • 243 次浏览 • 2021-01-05 11:50 • 来自相关话题

本文主要介绍 Flash 播放 AMR 格式 Base64码 音频。在此之前么有接触过 Flash ,接触 AS3 是一头雾水,不过幸好有 TypeScript 和 JavaScript 的基础看起来不是很费劲,现学现卖的就是开了 ”跳坑“ 之旅~~~1、实现... ...查看全部

本文主要介绍 Flash 播放 AMR 格式 Base64码 音频。

在此之前么有接触过 Flash ,接触 AS3 是一头雾水,不过幸好有 TypeScript 和 JavaScript 的基础看起来不是很费劲,现学现卖的就是开了 ”跳坑“ 之旅~~~

1、实现思路

起初一点实现思路都木有,不知道该从何做起,只知道用 Flash 播放 AMR ,度娘谷姐的一顿找,结果可想而知,没有糟糕,只有十分糟糕,哈哈。

后来想了想,凡事都得有个思路,不能闷头干,瞬间恍然大悟,为自己浪费的快一天的时间,感到羞愧和害怕…..

① Flash 都能播放哪些音频。

② 在 ActionScript 中AMR 是如何转换成 Flash 可播放的音频的。

③ JS 中如何调用 ActionScript 中方法,如何交互。

④ 如何把 SWF 文件嵌入到 HTML 页面中。

⑤ 如何把 AMR(Audio) 和 Flash 播放AMR 两种方式封装起来。

2、逐一破解

① Flash 都能播放哪些音频:

MP3 格式是 Flash 默认支持的音频格式,WAVE 格式需要转换可以播放,其他格式也是需要转换的,因为先做的 Chrome 下播放声音,对 WAVE 音频多少有些了解,所以决定从 WAVE 音频入手,所以按照上述的套路来 ”屡思路“:

(1) 不管如何转换,肯定要操作字节数组,所以第一步把 AMR 格式的 base64 码 转换为 ByteArray 数组。

(2) 如何把 AMR 的 ByteArray 转换成 WAVE 格式的 ByteArray 数组,毫无疑问 ,肯定需要解码的过程。

按照这两个小步骤逐一做,很快找到了 base64 的转码过程(开始是自己用 AS 实现了 JS 中的的 转码过程,可用但不完美,最终借鉴 github 上大牛的转换过程),但 AMR 转换 WAVE 这个就没有那么容易了,最终确定,AS 解 AMR 比较费劲,需要 用 C 语言来解码,然后用 CrossBirdge 生成可以供 Flash 调用的 SWC 文件。

OK,到这为止,第一步就完美解决了。

② 在 ActionScript 中AMR 是如何转换成 Flash 可播放的音频的:

    上文中有提到,需要用 C 语言 进行对 AMR 解码,下文中会给出 C 语言解码和生成 SWC 的教程(借鉴大牛的)。

③ JS 中如何调用 ActionScript 中方法,如何交互,下文中会贴出完整代码(一定要看注释、注释、注释),此处写出 JS 调用过程。

JS 代码:

function callFlashMethod() {
  // play 是 flash 代码中定义的 ExternalInterface.addCallback("play",this.play); 下文中会有详细介绍。
  thisMovie("嵌入页面上<object>的ID").play("base64str");
}
function thisMovie(movieName) {
    if (navigator.appName.indexOf("Microsoft") != -1) {
        return window[movieName]
    }
    else {
        return document[movieName]
    }
}
document.getElementById("playId").onclick = function(){
    callFlashMethod();
};

④ 如何把 SWF 文件嵌入到 HTML 页面中:

使用 swfobject.js 可以将 swf 文件嵌入到 HTML 页面中,参考资料 :http://www.cnblogs.com/Carpe-Diem/articles/2310831.html

⑤ 如何把 AMR(Audio) 和 Flash 播放AMR 两种方式封装起来:

有了上面的铺垫,轻而易举的就可以封装啦(主要看 isIE 为 true 的情况):

var RongIMLib;
(function (RongIMLib) {
    var RongIMVoice = (function () {
        function RongIMVoice() {
        }
        /**
        * 初始化声音库
        */
        RongIMVoice.init = function () {
            if (this.isIE) {
                var div = document.createElement("div");
                div.setAttribute("id", "flashContent");
                document.body.appendChild(div);
                var script = document.createElement("script");
                script.src = "http://cdn.ronghub.com/swfobject-2.0.0.min.js";
                var header = document.getElementsByTagName("head")[0];
                header.appendChild(script);
                setTimeout(function () {
                    var swfVersionStr = "11.4.0";
                    var flashvars = {};
                    var params = {};
                    params.quality = "high";
                    params.bgcolor = "#ffffff";
                    params.allowScriptAccess = "always";
                    params.allowfullscreen = "true";
                    var attributes = {};
                    attributes.id = "player";
                    attributes.name = "player";
                    attributes.align = "middle";
                    swfobject.embedSWF("http://cdn.ronghub.com/player-2.0.2.swf", "flashContent", "1", "1", swfVersionStr, null, flashvars, params, attributes);
                }, 200);
            }
            else {
                var list = ["http://cdn.ronghub.com/pcmdata-2.0.0.min.js", "http://cdn.ronghub.com/libamr-2.0.1.min.js"];
                for (var i = 0, len = list.length; i < len; i++) {
                    var script = document.createElement("script");
                    script.src = list[i];
                    document.head.appendChild(script);
                }
            }
            this.isInit = true;
        };
        /**
        * 开始播放声音
        * @param data {string} amr 格式的 base64 码
        * @param duration {number} 播放大概时长 用 data.length / 1024
        */
        RongIMVoice.play = function (data, duration) {
            this.checkInit("play");
            var me = this;
            if (me.isIE) {
                me.thisMovie().doAction("init", data);
            }
            else {
                me.palyVoice(data);
                me.onCompleted(duration);
            }
        };
        /**
        * 停止播放声音
        */
        RongIMVoice.stop = function () {
            this.checkInit("stop");
            var me = this;
            if (me.isIE) {
                me.thisMovie().doAction("stop");
            }
            else {
                if (me.element) {
                    me.element.stop();
                }
            }
        };
        /**
        * 播放声音时调用的方法
        */
        RongIMVoice.onprogress = function () {
            this.checkInit("onprogress");
        };
        RongIMVoice.checkInit = function (postion) {
            if (!this.isInit) {
                throw new Error("RongIMVoice not initialized,postion:" + postion);
            }
        };
        RongIMVoice.thisMovie = function () {
            return eval("window['player']");
        };
        RongIMVoice.onCompleted = function (duration) {
            var me = this;
            var count = 0;
            var timer = setInterval(function () {
                count++;
                me.onprogress();
                if (count >= duration) {
                    clearInterval(timer);
                }
            }, 1000);
            if (me.isIE) {
                me.thisMovie().doAction("play");
            }
        };
        RongIMVoice.base64ToBlob = function (base64Data, type) {
            var mimeType;
            if (type) {
                mimeType = { type: type };
            }
            base64Data = base64Data.replace(/^(.*)[,]/, '');
            var sliceSize = 1024;
            var byteCharacters = atob(base64Data);
            var bytesLength = byteCharacters.length;
            var slicesCount = Math.ceil(bytesLength / sliceSize);
            var byteArrays = new Array(slicesCount);
            for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
                var begin = sliceIndex * sliceSize;
                var end = Math.min(begin + sliceSize, bytesLength);
                var bytes = new Array(end - begin);
                for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
                    bytes[i] = byteCharacters[offset].charCodeAt(0);
                }
                byteArrays[sliceIndex] = new Uint8Array(bytes);
            }
            return new Blob(byteArrays, mimeType);
        };
        RongIMVoice.palyVoice = function (base64Data) {
            var reader = new FileReader(), blob = this.base64ToBlob(base64Data, "audio/amr"), me = this;
            reader.onload = function () {
                var samples = new AMR({
                    benchmark: true
                }).decode(reader.result);
                me.element = AMR.util.play(samples);
            };
            reader.readAsBinaryString(blob);
        };
        RongIMVoice.isIE = /Trident/.test(navigator.userAgent);
        RongIMVoice.isInit = false;
        return RongIMVoice;
    })();
    RongIMLib.RongIMVoice = RongIMVoice;
    //兼容AMD CMD
    if ("function" === typeof require && "object" === typeof module && module && module.id && "object" === typeof exports && exports) {
        module.exports = RongIMVoice;
    }
    else if ("function" === typeof define && define.amd) {
        define("RongIMVoice", [], function () {
            return RongIMVoice;
        });
    }
})(RongIMLib || (RongIMLib = {}));

 

截止到这里,Flash 播放 AMR 格式 base64 码 就说完了,主要是介绍下大概思路

以上是融云 SDK 里的源码,不过最近推出了直接使用 Audio 方式播放 AAC 格式的音频文件

原始文章连接:https://www.cnblogs.com/yuhongda0315/p/5224450.html

融云官网:https://www.rongcloud.cn

融云文档:https://docs.rongcloud.cn/v4


Web 端使用融云 SDK 集成实现滑动加载历史消息

IM即时通讯苏道 发表了文章 • 0 个评论 • 302 次浏览 • 2020-12-16 17:05 • 来自相关话题

刚接触即时通讯的项目,在使用融云的 SDK 来完成项目需求时,磕磕碰碰,死命看文档和提工单问融云的技术人员,真是一段痛并快乐的历程,哈哈哈!今天分享一个滑动加载获取历史消息的功能知识点先看获取历史消息的代码:var conversation ... ...查看全部

刚接触即时通讯的项目,在使用融云的 SDK 来完成项目需求时,磕磕碰碰,死命看文档和提工单问融云的技术人员,真是一段痛并快乐的历程,哈哈哈!今天分享一个滑动加载获取历史消息的功能

微信截图_20201216165629.png

知识点

先看获取历史消息的代码:

var conversation = im.Conversation.get({
  targetId: '接收方的 userId',
  type: RongIMLib.CONVERSATION_TYPE.PRIVATE
});
var option = {
  timestrap: +new Date(),
  count: 20
};
conversation.getMessages(option).then(function(result){
  var list = result.list; // 历史消息列表
  var hasMore = result.hasMore; // 是否还有历史消息可以获取
  console.log('获取历史消息成功', list, hasMore);
});

参数说明:
image

1、因为 Web 端没有本地存储,不提供本地获取方法,只能从远端获取
2、使用获取历史消息方法需要在开发者后台开启 IM 商用版 - 单群聊云存储 服务
3、每次最多只能获取 20 条历史消息
所以问题来了,获取历史消息的方法最多只能获取 20 条消息,那我想获取 20 条之前的消息,怎么办呢?
我们需要从它的参数来入手,解决思路就是改变参数 timestrap (时间戳),在每次调用 conversation.getMessages 成功获得历史消息列表 result.list 后,将 result.list 中 sentTime 值最小的赋值给 timestrap 然后滑动继续调用 conversation.getMessages 即可获取不同时间段的历史消息,也可以通过改变参数 order 来改变是获取该时间段之前的消息还是之后的消息。

是不是很简单,反正一开始我是迷糊了,所以记录一下,也分享给有需要的同学,不足的地方还请留言指正,大家共勉 ~ 加油!!!

下图是 result.list 中 message 的属性说明:

image



融云IM SDK web 端集成 — 表情采坑篇

IM即时通讯苏道 发表了文章 • 0 个评论 • 325 次浏览 • 2020-12-16 17:05 • 来自相关话题

公司集成 IM 使用的是融云的 IM SDK,我们有移动端,有 web 端,移动端同事集成表情时还是蛮顺利的貌似移动端 SDK 里就支持,一切都很顺理成章的样子,web 端就有些棘手了。web 端的表情是需要单独引入插件的,这点还是有点困惑的。一脸懵的看着文档... ...查看全部

公司集成 IM 使用的是融云的 IM SDK,我们有移动端,有 web 端,移动端同事集成表情时还是蛮顺利的貌似移动端 SDK 里就支持,一切都很顺理成章的样子,web 端就有些棘手了。web 端的表情是需要单独引入插件的,这点还是有点困惑的。

微信截图_20201216165823.png

一脸懵的看着文档,踩着优雅的脚步入坑,完成我的表情集成采坑之旅

这第一步不用说肯定是 SDK 的初始化和连接了。这些在文档的指引下都是很顺利的还很欣慰,还为文档的细致点过赞。

这第二步就是细化相关功能了。比如说发消息时可以带表情。

手动划重点专用~

按照文档https://docs.rongcloud.cn/v4/views/im/noui/guide/private/msgmanage/msgsend/web.html#emoji中的示例发了一条表情消息,完美成功了。看到文档中有 Emoji 插件,好奇的点开看看。好吧 ╮(╯▽╰)╭,如果要发表情消息需要集成插件。

没关系,没关系,一个插件而已。有文档有教程不怕不拍的 (^▽^)


开心的看着文档,优雅的写着代码~~

按步骤集成,自认为本人是个比较听话的,文档让咱干嘛就干嘛。决不搞特殊。

so ~ 一切都很完美很太平。开心的集成,拿到了了表,发消息也可以正常携带了,美美的给了移动端,你看成功了 ~

哈哈哈暗自窃喜中 ヾ( ̄ー ̄)X(^▽^)ゞ 奈何移动端同事也同样会给了我一份大礼给 web 发了个带表情的消息。点开一看。这什么。。。这什么。。。这一堆黑框是什么鬼 -_-||

额 ~ 我做错了什么。。。检查了变没问题啊,看了眼数据心里安慰了许多,原来收到的就是那么个黑框,于是理直气壮的去融云提了工单。


工单问答时间:

问:web 端收到的表情展示成方块

答:
1、web 端展示 emoji 时, 不管是通过历史消息还是消息监听器监听的消息, 都需要调用 emojiToHTML 转成 HTML 或者使用 symbolToEmoji 将 unicode(您说的小方块) 转化成原生 emoji 字符
2、不同浏览器, 不同设备, 展示的原生 Emoji 表情都不同
3、如需多端展示 Emoji 一致, 需使用 emojiToHTML 转化为 HTML 后再展示(此方法为以图片形式展示)

按照工单的提示对消息内容做了处理,调用了 emojiToHTML 方法。完美解决。


废话少说,上代码:

emojiToHtml:function(message){
  return RongIMLib.RongIMEmoji.emojiToHTML(message);
},
<pre class="Message-entry" v-html="emojiToHtml(message.content)">

由于开发使用了 vue 所以直接在标签上做了处理,在需要转换的消息类型上调用此方法即可。目前本人仅仅转换了文本类消息。

参考文案:

文档地址:https://docs.rongcloud.cn/v4/views/im/noui/guide/private/msgmanage/msgsend/web.html#emoji

融云官网:https://www.rongcloud.cn/