1 /*
  2 * YY开放平台JavaScript SDK
  3 * @create date 2012-01-06
  4 * @modify data 2013-12-16
  5 * @version 1.18 beta
  6 * ............................................................................
  7 * ............................................................................
  8 * yy open platform client javascript sdk 
  9 * 广州欢聚时代科技有限公司 版权所有 (c) 2005-2014 DuoWan.com [多玩游戏]
 10 
 11 ******************************************************************************
 12 * 更多开发资料请参考open.yy.com文档中心
 13 *******************************************************************************/
 14 
 15 //(function() {
 16 var yy_e_api_call_error = 0xF230; //十进制值62000  Api调用错误,错误的函数名称,错误的调用格式会返回此错误。
 17 var yy_e_api_param_error = 0xF231; //十进制值62001 Api调用参数错误,错误的参数个数和类型,会触发此错误。
 18 var yy_e_api_return_format_error = 0xF232; //十进制值62002 Api调用返回值格式错误。
 19 var yy_e_api_not_exist = 0xF233; //十进制值62003 Api不存在或者此YY版本下没有实现。
 20 //------------------------------IYYCommon------------------------------------------------------------------------
 21 /**
 22 * IYYCommon 接口。
 23 * @class 公共功能原型类,提供比如事件的侦听,取消侦听等公共功能。
 24 * @constructor
 25 */
 26 function IYYCommon() {
 27     /**
 28     * 保存事件侦听函数的对象,事件的类型作为eventsMap的key, key为事件唯一描述字符串,具体事件key 值,在每个接口有单独定义。
 29     * @field
 30     * @private
 31     */
 32     this.eventsMap = {};
 33 };
 34 
 35 /**
 36 * 增加侦听事件。
 37 * @param {string} eventType 事件的类型key,比如: IYY.ACTIVE,IYYChannel.CHANNEL_INFO_CHANGED
 38 * @param {function} listenerFunc 事件的侦听函数。
 39 */
 40 IYYCommon.prototype.addEventListener = function (eventType, listenerFunc) {
 41     if (arguments.length !== 2 || typeof (eventType) !== "string" || typeof (listenerFunc) !== "function") {
 42         throw "addEventListener param error";
 43     }
 44     if (this.eventsMap[eventType] === null || this.eventsMap[eventType] === undefined || this.eventsMap[eventType].length === 0) {
 45         this.eventsMap[eventType] = [listenerFunc];
 46         //第一次侦听,打开侦听订阅
 47         switch (eventType) {
 48             case IYY.ACTIVE:
 49                 callExternal("SubscribeYYEvent", eventType, true);
 50                 break;
 51             case IYYAudio.RECORD_ERR:
 52             case IYYAudio.RECORD_FINISHED:
 53                 callExternal("SubscribeAudioEvent", eventType, true);
 54                 break;
 55             case IYYChannel.CHANNEL_INFO_CHANGED:
 56             case IYYChannel.FOCUS_CHANNEL_CHANGED:
 57             case IYYChannel.SUB_CHANNEL_ADD:
 58             case IYYChannel.SUB_CHANNEL_DEL:
 59             case IYYChannel.USER_ENTER_CHANNEL:
 60             case IYYChannel.USER_LEAVE_CHANNEL:
 61                 callExternal("SubscribeChannelEvent", eventType, true);
 62                 break;
 63             case IYYChannelAppMsg.APP_LINK_CLICKED:
 64             case IYYChannelAppMsg.APP_LINK_EX_CLICKED:
 65                 callExternal("SubscribeAppMsgEvent", eventType, true);
 66                 break;
 67             case IYYChannelChat.CHAT:
 68             case IYYChannelChat.CHAT_FROM:
 69                 callExternal("SubscribeChannelChatEvent", eventType, true);
 70                 break;
 71             case IYYChannelMicList.USER_JOIN:
 72             case IYYChannelMicList.USER_LEAVE:
 73             case IYYChannelMicList.USER_MOVE:
 74             case IYYChannelMicList.CLEAR:
 75             case IYYChannelMicList.USER_LINKED:
 76             case IYYChannelMicList.USER_UNLINKED:
 77             case IYYChannelMicList.MODE_CHANGED:
 78             case IYYChannelMicList.CONTROLLED:
 79             case IYYChannelMicList.RELEASED:
 80             case IYYChannelMicList.DISABLE_JOIN:
 81             case IYYChannelMicList.ENABLE_JOIN:
 82             case IYYChannelMicList.TIME_CHANGED:
 83             case IYYChannelMicList.SPEAKING_STATE_CHANGED:
 84             case IYYChannelMicList.NOTIFICATION:
 85                 callExternal("SubscribeMicListEvent", eventType, true);
 86                 break;
 87             case IYYChannelUserListPopMenu.CLICKED:
 88                 callExternal("SubscribePopMenuEvent", eventType, true);
 89                 break;
 90             case IYYNet.RECV:
 91             case IYYNet.CLOSED:
 92                 callExternal("SubscribeNetEvent", eventType, true);
 93                 break;
 94             case IYYUser.USER_INFO_CHANGED:
 95                 callExternal("SubscribeUserEvent", eventType, true);
 96                 break;
 97             case IYYTempAudioSession.USER_ENTER_ROOM:
 98             case IYYTempAudioSession.USER_LEAVE_ROOM:
 99             case IYYTempAudioSession.SPEAKER_CHANGED:
100                 callExternal("SubscribeTempAudioSessionEvent", eventType, true);
101                 break;
102             case IYYFinance.BUY_RESPONSE:
103             case IYYFinance.BUY_GIFTS_RESPONSE:
104                 callExternal("SubscribeFinanceEvent", eventType, true);
105                 break;
106             case IYYVideo.CAMERA_STATUS:
107             case IYYVideo.PUBLISH_STATUS:
108             case IYYVideo.SUBSCRIBE_STATUS:
109                 callExternal("SubscribeVideoEvent", eventType, true);
110                 break;
111             default:
112         }
113 
114     }
115     else {
116         for (var i = 0; i < this.eventsMap[eventType].length; i++) {
117             if (this.eventsMap[eventType][i] === listenerFunc) {//是否已经存在
118                 return;//同一事件同一个函数只能侦听一次
119             }
120         }
121         this.eventsMap[eventType].push(listenerFunc);
122     }
123 
124 };
125 
126 /**
127 * 删除侦听事件。即删除指定事件的所有侦听函数。
128 * @param {string} eventType 事件的类型。
129 * @param {function} listenerFunc 要删除的事件的侦听函数。
130 */
131 IYYCommon.prototype.removeEventListener = function (eventType, listenerFunc) {
132     if (this.eventsMap[eventType] !== null && this.eventsMap[eventType] !== undefined) {
133         if (arguments.length === 1 && typeof (eventType) === "string") {
134             this.eventsMap[eventType] = []; //如果设置为null,dispatch时容易报错
135         }
136         else if (arguments.length === 2 && typeof (eventType) === "string" && typeof (listenerFunc) === "function") {
137             for (var i = this.eventsMap[eventType].length - 1; i >= 0; i--) {
138                 if (this.eventsMap[eventType][i] === listenerFunc) {
139                     this.eventsMap[eventType].splice(i, 1);//去掉侦听函数
140                 }
141             }
142         }
143         else {
144             throw "removeEventListener param error ";
145         }
146 
147         //取消侦听功能
148         if (this.eventsMap[eventType].length === 0) {
149             switch (eventType) {
150                 case IYY.ACTIVE:
151                     callExternal("SubscribeYYEvent", eventType, false);
152                     break;
153                 case IYYAudio.RECORD_ERR:
154                 case IYYAudio.RECORD_FINISHED:
155                     callExternal("SubscribeAudioEvent", eventType, false);
156                     break;
157                 case IYYChannel.CHANNEL_INFO_CHANGED:
158                 case IYYChannel.FOCUS_CHANNEL_CHANGED:
159                 case IYYChannel.SUB_CHANNEL_ADD:
160                 case IYYChannel.SUB_CHANNEL_DEL:
161                 case IYYChannel.USER_ENTER_CHANNEL:
162                 case IYYChannel.USER_LEAVE_CHANNEL:
163                     callExternal("SubscribeChannelEvent", eventType, false);
164                     break;
165                 case IYYChannelAppMsg.APP_LINK_CLICKED:
166                 case IYYChannelAppMsg.APP_LINK_EX_CLICKED:
167                     callExternal("SubscribeAppMsgEvent", eventType, false);
168                     break;
169                 case IYYChannelChat.CHAT:
170                 case IYYChannelChat.CHAT_FROM:
171                     callExternal("SubscribeChannelChatEvent", eventType, false);
172                     break;
173                 case IYYChannelMicList.USER_JOIN:
174                 case IYYChannelMicList.USER_LEAVE:
175                 case IYYChannelMicList.USER_MOVE:
176                 case IYYChannelMicList.CLEAR:
177                 case IYYChannelMicList.USER_LINKED:
178                 case IYYChannelMicList.USER_UNLINKED:
179                 case IYYChannelMicList.MODE_CHANGED:
180                 case IYYChannelMicList.CONTROLLED:
181                 case IYYChannelMicList.RELEASED:
182                 case IYYChannelMicList.DISABLE_JOIN:
183                 case IYYChannelMicList.ENABLE_JOIN:
184                 case IYYChannelMicList.TIME_CHANGED:
185                 case IYYChannelMicList.SPEAKING_STATE_CHANGED:
186                 case IYYChannelMicList.NOTIFICATION:
187                     callExternal("SubscribeMicListEvent", eventType, false);
188                     break;
189                 case IYYChannelUserListPopMenu.CLICKED:
190                     callExternal("SubscribePopMenuEvent", eventType, false);
191                     break;
192                 case IYYNet.RECV:
193                 case IYYNet.CLOSED:
194                     callExternal("SubscribeNetEvent", eventType, false);
195                     break;
196                 case IYYUser.USER_INFO_CHANGED:
197                     callExternal("SubscribeUserEvent", eventType, false);
198                     break;
199                 case IYYTempAudioSession.USER_ENTER_ROOM:
200                 case IYYTempAudioSession.USER_LEAVE_ROOM:
201                 case IYYTempAudioSession.SPEAKER_CHANGED:
202                     callExternal("SubscribeTempAudioSessionEvent", eventType, false);
203                     break;
204                 case IYYFinance.BUY_RESPONSE:
205                 case IYYFinance.BUY_GIFTS_RESPONSE:
206                     callExternal("SubscribeFinanceEvent", eventType, false);
207                     break;
208                 case IYYVideo.CAMERA_STATUS:
209                 case IYYVideo.PUBLISH_STATUS:
210                 case IYYVideo.SUBSCRIBE_STATUS:
211                     callExternal("SubscribeVideoEvent", eventType, false);
212                     break;
213                 default:
214             }
215         }
216 
217     }
218 };
219 
220 /**
221 * 触发事件,注意:此接口,在外部不要调用,外部调用此函数触发的事件,为无效事件
222 * @param {String} eventType 事件类型。 
223 * @param {String} eventData 事件数据。 
224 * @private
225 */
226 IYYCommon.prototype.dispatchEvent = function(eventType, eventData) {
227     //触发事件
228     if (this.eventsMap[eventType] === null || this.eventsMap[eventType] === undefined) return;
229     for (var i = 0; i < this.eventsMap[eventType].length; i++) {
230         switch (arguments.length) {
231             case 1:
232                 this.eventsMap[eventType][i](); //不需要信息的事件
233                 break;
234             case 2:
235                 this.eventsMap[eventType][i](eventData);
236                 break;
237             default:
238         }
239     }
240 };
241 //--------------------------------------set debug mode-----------------------
242 //设置为true时,会在id为txtConsole的textarea文本框中输出调试信息
243 var debugMode = false;
244 
245 //--------------------------------------IYY----------------------------------
246 /**
247 * IYY 构造函数。
248 * @extends IYYCommon
249 * @class yy接口入口,获取到yy的其他接口和方法。
250 * @constructor
251 */
252 function IYY() {
253     /**
254     * 获取语音接口。
255     * @field
256     * @type IYYAudio
257     * @see IYYAudio   
258     */
259     this.audio = new IYYAudio();
260 
261     /**
262     * 获取频道接口。
263     * @field
264     * @type IYYChannel
265     * @see IYYChannel   
266     */
267     this.channel = new IYYChannel();
268 
269     /**
270     * 获取简单存储接口。  
271     * @field
272     * @type IYYCloud
273     * @see IYYCloud
274     */
275     this.cloud = new IYYCloud();
276 
277     /**
278     * 获取财务接口。  
279     * @field
280     * @type IYYFinance
281     * @see IYYFinance
282     */
283     this.finance = new IYYFinance();
284 
285     /**
286     * 获取IM接口。
287     * @field
288     * @type IYYIM
289     * @see IYYIM    
290     */
291     this.im = new IYYIM();
292 
293     /**
294     * 获取网络接口。
295     * @field
296     * @type IYYNet
297     * @see IYYNet
298     */
299     this.net = new IYYNet();
300 
301     /**
302     * 获取安全接口。
303     * @field
304     * @type IYYSecurity
305     * @see IYYSecurity
306     */
307     this.security = new IYYSecurity();
308 
309     /**
310     * 获取当前用户信息。
311     * @field
312     * @see IYYUser
313     * @type IYYUser
314     */
315     this.user = new IYYUser();
316 
317     /**
318     * 获取临时语音接口。
319     * @field
320     * @see IYYTempAudioSession
321     * @type IYYTempAudioSession
322     */
323     this.tempAudioSession = new IYYTempAudioSession();
324     /**
325     * 获取应用互动接口。
326     * @field
327     * @see IYYInteraction
328     * @type IYYInteraction
329     */
330     this.interaction = new IYYInteraction();
331 
332     /**
333     * 获取视频直播接口。
334     * @field
335     * @see IYYVideo
336     * @type IYYVideo
337     * @private
338     */
339     this.video = new IYYVideo();
340 
341 
342     var result = callExternal("IYY_GetVersion");
343     var ver;//;= new YYVersion();
344     if (result.ret === 0) {
345         ver = { ret: 0, majorVersion: result.main_version, minorVersion: result.sub_version };
346     } else {
347         ver = result;
348     }
349 
350     /**
351     * 获取YY API的版本,是一个Object对象:
352     * @field
353     * @example
354     * 版本对象包括属性如下:
355     * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。
356     * <b>majorVersion</b>: Number类型 主版本号
357     * <b>minorVersion</b>: Number类型 次版本号
358     * @example
359     * 成功的返回值示例:{ ret:0, majorVersion:1, minorVersion:13 }
360     * 失败的返回值示例:{ ret:984832}
361     * @type Object
362     */
363     this.version = ver;
364     var retv = callExternal("IYYEx_GetYYVersion");
365 
366     /**
367     * 获取YY客户端的版本信息。返回YY的版本,是一个Object对象。
368     * @field
369     * @example
370     * 版本对象包括属性如下:
371     * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。
372     * <b>version</b>: String类型 YY客户端主版本信息。发布版本典型的版本格式为"YY 4.17.0.3",注意空格。获取失败时返回空字符串。
373     * @example
374     * 成功的返回值示例:{ ret:0, version:"YY 4.17.0.3" }
375     * 失败的返回值示例:{ ret:984832}
376     * @type Object
377     */
378     this.yyVersion = retv;
379     
380     /**
381     * 设置flash对象的Id,能够根据此Id获得flash对象,调用flash中的方法。设置后YY的回调事件才能转发给flash。
382     * @field
383     * @type String
384     */
385     this.flashId = "";
386 
387 
388 
389     //关闭所有事件,提高效率
390     
391     try
392     {
393         callExternal("SubscribeAudioEvent","ALL", false);
394         callExternal("SubscribeAppMsgEvent","ALL", false);
395         callExternal("SubscribeChannelEvent","ALL", false);
396         callExternal("SubscribeYYEvent","ALL", false);
397         callExternal("SubscribeMicListEvent","ALL", false);
398         callExternal("SubscribeUserEvent","ALL", false);
399         callExternal("SubscribeNetEvent","ALL", false);
400         callExternal("SubscribePopMenuEvent","ALL", false);
401         callExternal("SubscribeTempAudioSessionEvent", "ALL", false);
402         callExternal("SubscribeFinanceEvent", "ALL", false);
403         callExternal("SubscribeChannelChatEvent", "ALL", false);
404         callExternal("SubscribeVideoEvent", "ALL", false);
405     } catch (ex) {
406         yytrace("xxxSubscribe Event Errorxxxx");
407     }
408 };
409 
410 IYY.prototype = new IYYCommon();
411 /**
412 * 获取应用的展现方式。
413 * @returns 返回应用展现方式,是Object对象格式,具体属性如下:<br/>
414 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。 <br/>
415 * <b>mode</b>: String类型 应用的展现方式。其中<br/>
416 * SubWindow=公告,应用在公告区域展现。<br/>
417 * PopWindow=弹窗,应用弹出一个窗口展现。<br/>
418 * FullTemplate=全模板,在频道窗口右侧展现,会隐藏公屏聊天区域。<br/>
419 * EmbedTemplate=半模板,应用在频道窗口中间位置展现,保留公屏聊天区域。<br/>
420 * TabPage=tab页,应用在一个新Tab页中展现。<br/>
421 * <br/>
422 * @example 
423 * 使用示例:
424 * var result=yy.getWebAppShowMode();
425 * if(result.ret==0)
426 * {
427 *     document.getElementById("txtLog").innerHTML="应用展现模式为 mode="+result.mode;
428 * }
429 * else
430 * {
431 *     document.getElementById("txtLog").innerHTML="获取出错,错误码ret="+result.ret;
432 * }
433 * 成功的返回值示例:{ ret:0,mode:"PopWindow"}
434 * 失败的返回值示例:{ ret:984832}
435 * @type Object
436 */
437 IYY.prototype.getWebAppShowMode = function () {
438     var result = callExternal("IYYEx_GetWebAppShowMode");
439     if (result.ret == 0) {
440         return { ret: 0, mode: result.mode };
441     }
442     else {
443         return result;
444     }
445 };
446 
447 /**
448 * 应用激活事件。当应用运行时,应用图标在应用盒子或者其他应用入口被点击时产生的事件。
449 * @field
450 * @example
451 * 侦听函数格式: function(eventData){    } 
452 * 侦听函数参数说明: 
453 * eventData.activeCode: Number类型,正整数,表示点击的来源,0=点击来源于应用盒子图标。
454 *
455 * @example
456 * 使用示例:
457 * yy.addEventListener(IYY.ACTIVE,onActive);
458 *
459 * function onActive(eventData)
460 * {
461 *    document.getElementById("txtLog").innerHTML="点击来源:"+eventData.activeCode;
462 * }
463 */
464 IYY.ACTIVE = "YY_ACTIVE";
465 
466 //------------------------------IYYAudio------------------------------
467 
468 /**
469 * IYYAudio 构造函数。
470 * @extends IYYCommon
471 * @class 语音控制接口,提供处理YY的音频信息,比如录音的控制等。
472 * @constructor
473 */
474 function IYYAudio() {
475 
476 };
477 
478 IYYAudio.prototype = new IYYCommon();
479 /**
480 * 开始录音
481 * @param {String} fileName 指定录音文件的文件名,不需要路径。
482 * 格式为MP3,会录制到固定的路径中,如果两次录音指定了同一个文件,第二次的会被覆盖。不指定文件名的话系统会使用默认名称。
483 * @returns 返回调用是否成功,是一个Object对象,具体属性如下。<br/>
484 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
485 * @example
486 * 使用示例:
487 * var result=yy.audio.starRecord();
488 * 成功的返回值示例:{ ret:0}
489 * 失败的返回值示例:{ ret:984832}
490 * @type Object
491 */
492 IYYAudio.prototype.startRecord = function(fileName) {
493     var result;
494     if (arguments.length === 0) {
495         result = callExternal("IAudio_StartRecord");
496     }
497     else if (arguments.length > 1) {
498         return { ret: yy_e_api_param_error }; //出错,参数错误
499     }
500     else {
501         if (typeof (fileName) !== "string") return { ret: yy_e_api_param_error };
502         result = callExternal("IAudio_StartRecord",fileName);
503     }
504     return result;
505 };
506 /**
507 * 停止录音
508 * @returns 返回调用是否成功,是一个Object对象,具体属性如下。<br/>
509 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
510 * @type Object
511 */
512 IYYAudio.prototype.stopRecord = function() {
513     var result = callExternal("IAudio_StopRecord");
514     return result;
515 };
516 
517 /**
518 * 打开卡拉ok效果,即播放伴奏。<br>
519 * 权限规则如下:<br>
520 * OW,VP,MA 在当前的频道内,在任何模式下都可以开启和关闭卡拉OK功能。
521 * CA,CA2 在当前频道内拥有管理权限的子频道内可以开启和关闭卡拉OK功能。
522 * VIP,G,R,U必须在自由模式下或者麦序模式下到首位麦序的时候可以开启和关闭卡拉OK功能。
523 * 字母代表的意义如下:<br>
524 * 游客(U),临时嘉宾(G),嘉宾(VIP),会员(R),二级子频道管理员(CA2),子频道管理员(CA),全频道管理员(MA),频道总管理(VP),频道所有者(OW)<br>
525 * @returns 返回调用是否成功,是一个Object对象,具体属性如下。<br/>
526 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
527 * @type Object
528 */
529 IYYAudio.prototype.openKaraoke = function() {
530     var result = callExternal("IAudio_OpenKaraoke");
531     return result;
532 };
533 /**
534 * 关闭卡拉ok效果,,即停止伴奏。权限规则和openKaraoke方法相同。
535 * @see #openKaraoke
536 * @returns 返回调用是否成功,是一个Object对象,具体属性如下。<br/>
537 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
538 * @type Object
539 */
540 IYYAudio.prototype.closeKaraoke = function() {
541     var result = callExternal("IAudio_CloseKaraoke");
542     return result;
543 };
544 
545 /**
546 * 开启混响效果。
547 * @returns 返回调用是否成功,是一个Object对象,具体属性如下。<br/>
548 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
549 * @type Object
550 */
551 IYYAudio.prototype.enableAudioMixing = function () {
552     var result = callExternal("IAudio_EnableAudioMixing");
553     return result;
554 };
555 /**
556 * 关闭混响效果。
557 * @returns 返回调用是否成功,是一个Object对象,具体属性如下。<br/>
558 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
559 * @type Object
560 */
561 IYYAudio.prototype.disableAudioMixing = function () {
562     var result = callExternal("IAudio_DisableAudioMixing");
563     return result;
564 };
565 
566 /**
567 * 设置伴奏播放器路径。
568 * @param {String} filePathName 指定播放器的路径和文件名。
569 * @returns 返回操作结果,是Object对象格式,具体属性如下:<br/>
570 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。 <br/>
571 * <b>originPlayerPath</b>: String类型 为原来的播放器路径。<br/>
572 * <b>originSoftwareMixEnable</b>: Boolean类型 为原来是否使用软件卡拉ok混音。<br/>
573 * @example 
574 * 使用示例:
575 * var result=yy.audio.setKaraokePlayerPath("c:\aaa\bb.exe");
576 * if(result.ret==0)
577 * {
578 *     document.getElementById("txtLog").innerHTML="设置完成,原来路径="+result.originPlayerPath+" 原来混音状态="+result.originSoftwareMixEnable;
579 * }
580 * else
581 * {
582 *     document.getElementById("txtLog").innerHTML="设置出错,错误码ret="+result.ret;
583 * }
584 * 成功的返回值示例:{ ret:0,originPlayerPath:"C:\\Program Files\\StormII\\Storm.exe",originSoftwareMixEnable:false}
585 * 失败的返回值示例:{ ret:984832}
586 * @type Object
587 */
588 IYYAudio.prototype.setKaraokePlayerPath = function (filePathName) {
589     if (arguments.length != 1) return { ret: yy_e_api_param_error }; //出错,参数错误
590     if (typeof (filePathName) !== "string") return { ret: yy_e_api_param_error };
591     var result = callExternal("IAudio_SetKaraokePlayerPath", filePathName);
592     if (result.ret == 0) {
593         return { ret: 0, originPlayerPath: result.origin_player_path, originSoftwareMixEnable: result.origin_software_mix_enable };
594     } else {
595         return result;
596     }
597 };
598 
599 /**
600 * 恢复伴奏播放器路径。如果上一次设置的时候保存了原始的播放器路径等信息,可以调用此方法恢复。
601 * @param {String} filePathName 原来的播放器的路径和文件名。
602 * @param {Boolean} mixEnable 原来是否使用软件卡拉ok混音。
603 * @returns 返回调用是否成功,是一个Object对象,具体属性如下。<br/>
604 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
605 * @type Object
606 */
607 IYYAudio.prototype.resetKaraokePlayerPath = function (filePathName,mixEnable) {
608     if (arguments.length != 2) return { ret: yy_e_api_param_error }; //出错,参数错误
609     if (typeof (filePathName) !== "string") return { ret: yy_e_api_param_error };
610     if (typeof (mixEnable) !== "boolean") return { ret: yy_e_api_param_error };
611     var result = callExternal("IAudio_ResetKaraokePlayerPath", filePathName, mixEnable);
612     return result;
613 };
614 
615 
616 /**
617 * 音频录音出错事件。录音出错的时候会触发。
618 * @field
619 * @example
620 * 侦听函数格式: function(eventData){    } 
621 * 侦听函数参数说明: 
622 * eventData.errCode: Number类型,整数,录音出错代码。
623 *
624 * @example
625 * 使用示例:
626 * yy.audio.addEventListener(IYYAudio.RECORD_ERR,onRecordError);
627 *
628 * function onRecordError(eventData)
629 * {
630 *    document.getElementById("txtLog").innerHTML=eventData.errCode;
631 * }
632 */
633 IYYAudio.RECORD_ERR = "YY_RECORD_ERR";
634 
635 
636 /**
637 * 音频录音完成事件。录音完成的时候会触发。
638 * @field
639 * @example
640 * 侦听函数格式: function(eventData){    } 
641 * 侦听函数参数说明: 
642 * eventData.result: Number类型,表示录音结果的整数。 0=录音正确,非0值表示录音过程中有错误。
643 * eventData.fileName: String类型 录音文件的路径和文件名 。
644 *
645 * @example
646 * 使用示例:
647 * yy.audio.addEventListener(IYYAudio.RECORD_FINISHED,onRecordFinish);
648 *
649 * function onRecordFinish(eventData)
650 * {
651 *    if(eventData.result==0)
652 *    {
653 *       document.getElementById("txtLog").innerHTML="录好的文件在:"+eventData.fileName;
654 *    }
655 * }
656 */
657 IYYAudio.RECORD_FINISHED = "YY_RECORD_FINISHED";
658 
659 //-------------------------------------IYYChannel-----------------------------------
660 /**
661 * IYYChannel 构造函数。
662 * @extends IYYCommon
663 * @class 频道接口,提供对频道的操作和交互。
664 * @constructor
665 */
666 function IYYChannel() {
667 
668     /**
669     * 获取用户菜单接口。
670     * @type IYYChannelUserListPopMenu
671     * @see IYYChannelUserListPopMenu    
672     * @field
673     */
674     this.userListPopMenu = new IYYChannelUserListPopMenu();
675     /**
676     * 获取麦序接口。
677     * @type IYYChannelMicList
678     * @see IYYChannelMicList
679     * @field
680     */
681     this.micList = new IYYChannelMicList();
682     /**
683     * 获取频道应用消息接口。
684     * @type IYYChannelAppMsg
685     * @see IYYChannelAppMsg
686     * @field
687     */
688     this.appMsg = new IYYChannelAppMsg();
689 
690     /**
691     * 获取频道用户控制接口。
692     * @type IYYChannelUserController
693     * @see IYYChannelUserController
694     * @field
695     */
696     this.userController = new IYYChannelUserController();
697     
698     /**
699     * 获取接待频道接口。
700     * @type IYYReceptionChannel
701     * @see IYYReceptionChannel
702     * @field
703     */
704     this.receptionChannel = new IYYReceptionChannel();    
705     
706     /**
707     * 获取频道 tab页接口。
708     * @type IYYChannelTabPage
709     * @see IYYChannelTabPage
710     * @field
711     */
712     this.tabPage = new IYYChannelTabPage();
713 
714     /*
715     * 获取公屏聊天和私聊接口。
716     * @type IYYChannelChat
717     * @see IYYChannelChat
718     */
719     this.chat = new IYYChannelChat();
720 
721 };
722 
723 IYYChannel.prototype = new IYYCommon();
724 
725 /**
726 * 获取当前所在的大频道信息
727 * @returns 返回当前频道信息,是一个Object对象,具体属性如下。<br/>
728 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
729 * <b>longId</b>: Number类型 频道的长位Id。<br/>
730 * <b>shortId</b>: Number类型 频道的短位Id,如果没有,同长位Id一致。<br/>
731 * <b>name</b>: String类型 频道的名称。<br/>
732 * <b>userCount</b>: Number类型 所在子频道用户数量。<br/>
733 * <b>totalUserCount</b>: Number类型 大频道全部用户数量。<br/>
734 * <b>channelType</b>: Number类型 游戏=0 娱乐=1 其他=2 教育=3。<br/>
735 * <b>channelPoints</b>: Number类型 频道的积分。<br/>
736 * @type Object
737 * @example 
738 * 使用示例:
739 * var cInfo=yy.channel.getCurrentChannelInfo();
740 * 成功的返回值示例:{ ret:0,longId:88995544,shortId:1234,name:"我的测试频道",userCount:9,totalUserCount:25,channelType:0,channelPoints:4958}
741 * 失败的返回值示例:{ ret:984832}
742 */
743 IYYChannel.prototype.getCurrentChannelInfo = function() {
744     var result = callExternal("IChannel_GetCurrentChannelInfo");
745     if (result.ret === 0) {
746         return parseChannelInfo(result);
747     }
748     else {
749         return result;
750     }
751 };
752 
753 /**
754 * 获取当前所在的子频道信息
755 * @returns 返回当前子频道信息,是一个Object对象。返回信息格式同getCurrentChannelInfo一致。
756 * @type Object
757 * @see #getCurrentChannelInfo
758 */
759 IYYChannel.prototype.getCurrentSubChannelInfo = function() {
760     var result = callExternal("IChannel_GetCurrentSubChannelInfo");
761     if (result.ret === 0) {
762 
763         return parseChannelInfo(result);
764     }
765     else {
766         return result;
767     }
768 };
769 
770 /**
771 * 获取当前大频道中,指定的子频道或者根频道的频道信息。
772 * @returns 返回指定频道信息,是一个Object对象。返回信息格式同getCurrentChannelInfo一致。
773 * @param {Number} cid 指定的频道的id <b>是频道的长位Id</b> 。
774 * @type Object
775 * @see #getCurrentChannelInfo    
776 * 
777 */
778 IYYChannel.prototype.getChannelInfo = function(cid) {
779     if (arguments.length !== 1) return null;
780     if (typeof cid !== "number" || isNaN(cid)) return null;
781     var result = callExternal("IChannel_GetChannelInfo", cid);
782     if (result.ret === 0) {
783         return parseChannelInfo(result);
784     }
785     else {
786         return result;
787     }
788 };
789 
790 
791 /**
792 * 获取当前根频道id。
793 * @returns 返回当前根频道的频道长位id,具体属性如下。<br/>
794 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
795 * <b>cid</b>: Number类型 当前频道根频道的长位Id。<br/>
796 * @type Object
797 * @example 
798 * 使用示例:
799 * var result=yy.channel.getRootChannelId();
800 * if(result.ret==0)
801 * {
802 *   document.getElementById("txtLog").innerHTML="根频道Id="+result.cid;
803 * }
804 * 成功的返回值示例:{ ret:0,cid:88995544}
805 * 失败的返回值示例:{ ret:984832}
806 */
807 IYYChannel.prototype.getRootChannelId = function() {
808     var result = callExternal("IChannel_GetRootChannelId");
809     if (result.ret === 0) {
810         return { ret: 0, cid: result.long_id };
811     }
812     else {
813         return result;
814 
815     }
816 };
817 
818 
819 /**
820 * 获取指定频道的所有子频道的id。
821 * @param {Number} cid 指定频道的的长位id,必须是在当前大频道中的一个频道。 
822 * @returns 返回所有子频道的长位id。<br/>
823 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
824 * <b>cids</b>: Array类型 回所有子频道的长位id,id保存在一个数组中<br/>
825 * @type Object
826 * @example 
827 * 使用示例:
828 * var result=yy.channel.getSubChannelIds(45467889);
829 * if(result.ret==0)
830 * {
831 *   document.getElementById("txtLog").innerHTML="所有子频道Id为"+result.cids;
832 * }
833 * 成功的返回值示例:{ ret:0,cids:[88995544,99898888,33334445]}
834 * 失败的返回值示例:{ ret:984832}
835 */
836 IYYChannel.prototype.getSubChannelIds = function(cid) {
837     if (arguments.length !== 1) return [];
838     if (typeof cid !== "number" || isNaN(cid)) return [];
839     var result = callExternal("IChannel_GetSubChannelIds", cid);
840     if (result.ret === 0) {
841         return { ret: 0, cids: result.ids.concat() };
842     }
843     else {
844         return [];
845     }
846 };
847 
848 /**
849 * 获取指定频道的用户的uid。<b>频道超过200人时只随机获取200人</b>
850 * @param {Number} cid 指定频道的的长位id,必须是在当前大频道中的一个频道。 
851 * @returns 返回在该频道中前200个用户uid。<br/>
852 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
853 * <b>userList</b>: Array类型 返回在该频道中前200个用户uid,uid保存在一个数组中。<br/>
854 * @type Object
855 * @example 
856 * 使用示例:
857 * var result=yy.channel.getUserList(45467889);
858 * if(result.ret==0)
859 * {
860 *   document.getElementById("txtLog").innerHTML="在45467889频道中的用户为:"+result.userList;
861 * }
862 * 成功的返回值示例:{ ret:0,userList:[1234444,2234455,3311344]}
863 * 失败的返回值示例:{ ret:984832}
864 */
865 IYYChannel.prototype.getUserList = function (cid) {
866     if (arguments.length !== 1) return [];
867     if (typeof cid !== "number" || isNaN(cid)) return [];
868     var result = callExternal("IChannelUserList_GetUserList", cid);
869     if (result.ret === 0) {
870         return { ret: 0, userList: result.list.concat() };
871     }
872     else {
873         return result;
874     }
875 };
876 
877 /**
878 * 获取频道风格。用来判断是普通频道风格还是精彩世界风格。
879 * @returns 返回频道风格,具体属性如下。<br/>
880 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
881 * <b>style</b>: Number类型 当前频道频道风格,0=普通频道,1=精彩世界。<br/>
882 * @type Object
883 * @example 
884 * 使用示例:
885 * var result=yy.channel.getChannelStyle();
886 * if(result.ret==0)
887 * {
888 *   document.getElementById("txtLog").innerHTML="频道风格: "+ (result.style == 0 ? "普通频道" : "精彩世界");
889 * }
890 * 成功的返回值示例:{ ret:0,cid:88995544}
891 * 失败的返回值示例:{ ret:984832}
892 */
893 IYYChannel.prototype.getChannelStyle=function() {
894     return callExternal("IChannel_GetChannelStyle");
895 };
896 /**
897 * 当前频道信息变化事件。用户<b>当前</b>所在的频道(子频道或者根频道)信息变化时会触发。
898 * @field
899 * @example
900 * 侦听函数格式: function(eventData){    } 
901 * 侦听函数参数说明: 
902 * eventData: Object类型 是YYChannelInfo对象,保存频道的新信息。
903 *
904 * @example
905 * 使用示例:
906 * yy.channel.addEventListener(IYYChannel.CHANNEL_INFO_CHANGED,onChannelInfoChanged);
907 *
908 * function onChannelInfoChanged(eventData)
909 * {
910 *     document.getElementById("txtLog").innerHTML="发生变化的频道号:"+eventData.longId+" 名称为:"+eventData.name;
911 * }
912 */
913 IYYChannel.CHANNEL_INFO_CHANGED = "YY_CHANNEL_INFO_CHANGED";
914 
915 /**
916 * 切换频道事件。用户在大频道中切换频道的时候会触发。
917 * @field
918 * @example
919 * 侦听函数格式: function(eventData){    } 
920 * 侦听函数参数说明: 
921 * eventData.departedId: Number类型 离开的频道的长位id。
922 * eventData.nowId: Number类型 进入的频道的长位id。
923 *
924 * @example
925 * 使用示例:
926 * yy.channel.addEventListener(IYYChannel.FOCUS_CHANNEL_CHANGED,onFocusChanged);
927 *
928 * function onFocusChanged(eventData)
929 * {
930 *     document.getElementById("txtLog").innerHTML="离开:"+eventData.departedId+" 进入了"+eventData.nowId;
931 * }
932 */
933 IYYChannel.FOCUS_CHANNEL_CHANGED = "YY_FOCUS_CHANNEL_CHANGED";
934 
935 
936 /**
937 * 子频道增加事件。子频道创建的时候会触发此事件。
938 * @field
939 * @example
940 * 侦听函数格式: function(eventData){    } 
941 * 侦听函数参数说明: 
942 * eventData.cid: Number类型 增加的子频道的长位id。
943 * eventData.pcid: Number类型 增加到哪个频道下,长位id。
944 * @example
945 * 使用示例:
946 * yy.channel.addEventListener(IYYChannel.SUB_CHANNEL_ADD,onChannelAdd);
947 *
948 * function onChannelAdd(eventData)
949 * {
950 *     document.getElementById("txtLog").innerHTML="新的频道"+eventData.cid+"位于"+eventData.pcid+"下面";
951 * }
952 */
953 IYYChannel.SUB_CHANNEL_ADD = "YY_SUB_CHANNEL_ADD";
954 
955 /**
956 * 子频道删除事件。子频道被删除时触发此事件。
957 * @field
958 * @example
959 * 侦听函数格式: function(eventData){    } 
960 * 侦听函数参数说明: 
961 * eventData.cid: Number类型 被删除的子频道长位id。
962 *
963 * @example
964 * 使用示例:
965 * yy.channel.addEventListener(IYYChannel.SUB_CHANNEL_DEL,onChannelDel);
966 *
967 * function onChannelDel(eventData)
968 * {
969 *     document.getElementById("txtLog").innerHTML="被删除的子频道:"+eventData.cid;
970 * }
971 */
972 IYYChannel.SUB_CHANNEL_DEL = "YY_SUB_CHANNEL_DEL";
973 
974 /**
975 * 用户进入当前大频道事件。当用户进入当前大频道中任一频道就会触发。
976 * @field
977 * @example
978 * 侦听函数格式: function(eventData){    } 
979 * 侦听函数参数说明: 
980 * eventData.uid: Number类型 进入频道的用户uid。
981 * eventData.cid: Number类型 进入时,所在的那个频道的长位id。  
982 * @example
983 * 使用示例:
984 * yy.channel.addEventListener(IYYChannel.USER_ENTER_CHANNEL,onUserEnter);
985 *
986 * function onUserEnter(eventData)
987 * {
988 *     document.getElementById("txtLog").innerHTML="有新用户"+eventData.uid+"进入到"+eventData.cid+"频道";
989 * }
990 */
991 IYYChannel.USER_ENTER_CHANNEL = "YY_USER_ENTER_CHANNEL";
992 
993 
994 /**
995 * 用户离开当前大频道事件。当有用户离开当前大频道就会触发。
996 * @field
997 * @example
998 * 侦听函数格式: function(eventData){    } 
999 * 侦听函数参数说明: 
1000 * eventData.uid: Number类型 离开频道的用户uid。
1001 * eventData.cid: Number类型 离开大频道时所处的频道的长位id。
1002 * @example
1003 * 使用示例:
1004 * yy.channel.addEventListener(IYYChannel.USER_LEAVE_CHANNEL,onUserLeave);
1005 *
1006 * function onUserLeave(eventData)
1007 * {
1008 *     document.getElementById("txtLog").innerHTML="用户"+eventData.uid+"离开了"+eventData.cid+"频道";
1009 * }
1010 */
1011 IYYChannel.USER_LEAVE_CHANNEL = "YY_USER_LEAVE_CHANNEL";
1012 
1013 
1014 //-------------------------------------IYYChannelAppMsg-----------------------------------
1015 /**
1016 * IYYChannelAppMsg 构造函数
1017 * @extends IYYCommon
1018 * @class 频道应用消息接口,提供频道的应用消息发送和响应等操作,应用消息出现在应用盒子的应用消息选项卡中和公告栏下方。
1019 * @constructor
1020 */
1021 function IYYChannelAppMsg() {
1022 };
1023 
1024 IYYChannelAppMsg.prototype = new IYYCommon();
1025 
1026 
1027 /**
1028 * 发送应用消息到子频道。所有该子频道在线用户才能收到。
1029 * @param {Number} subChannelId 子频道长位id。    
1030 * @param {String} msg 消息内容,最大长度200字节。
1031 * @param {Number} linkstart 内容中超链接开始位置,必须为正整数。
1032 * @param {Number} linkend 内容中超链接结束位置,必须为正整数。    
1033 * @param {Number} token  设置token,消息标记,必须为正整数。  
1034 * @returns 返回调用是否成功,是一个Object对象,具体属性如下。<br/>
1035 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1036 * @type Object
1037 */
1038 IYYChannelAppMsg.prototype.sendMsgToSubChannel = function(subChannelId, msg, linkstart, linkend, token) {
1039     if (arguments.length !== 5) return { ret: yy_e_api_param_error };
1040     if (typeof subChannelId !== "number" || typeof msg !== "string" || typeof linkstart !== "number" || typeof linkend !== "number" || typeof token !== "number") return { ret: yy_e_api_param_error };
1041     if (isNaN(subChannelId) || isNaN(linkstart) || isNaN(linkend) || isNaN(token)) return { ret: yy_e_api_param_error };
1042     msg = msg.replace(/\\/g, "\\\\"); //替换斜杠
1043     msg = msg.replace(/\"/g, "\\\""); //替换双引号
1044     var result = callExternal("IChannelAppMsg_SendMsgToSubChannel", subChannelId, msg, linkstart, linkend, token);
1045     return result;
1046 };
1047 
1048 
1049 /**
1050 * 发送应用消息给指定用户。用户必须在同一大频道中,且必须在线才能收到。
1051 * @param {Array} userList 存有目标用户uid的数组。    
1052 * @param {String} msg 消息内容 最大长度200字节。
1053 * @param {Number} linkstart 内容中超链接开始位置,必须为正整数。
1054 * @param {Number} linkend 内容中超链接结束位置,必须为正整数。    
1055 * @param {Number} token  设置token,消息标记,必须为正整数。 
1056 * @returns 返回调用是否成功,是一个Object对象,具体属性如下。<br/>
1057 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1058 * @type Object
1059 */
1060 IYYChannelAppMsg.prototype.sendMsgToUsers = function(userList, msg, linkstart, linkend, token) {
1061     if (arguments.length !== 5) return { ret: yy_e_api_param_error };
1062     if (!(userList instanceof Array) || typeof msg !== "string" || typeof linkstart !== "number" || typeof linkend !== "number" || typeof token !== "number") return { ret: yy_e_api_param_error };
1063     if (isNaN(linkstart) || isNaN(linkend) || isNaN(token)) return { ret: yy_e_api_param_error };
1064     msg = msg.replace(/\\/g, "\\\\"); //替换斜杠
1065     msg = msg.replace(/\"/g, "\\\""); //替换双引号
1066     var result = callExternal("IChannelAppMsg_SendMsgToUsers", userList, msg, linkstart, linkend, token);
1067     return result;
1068 };
1069 
1070 /**
1071 * 发送应用消息到子频道。所有该子频道在线用户才能收到。可以发送包含多个链接的消息。
1072 * @param {Number} subChannelId 子频道长位id。    
1073 * @param {Number} token  设置token,消息标记,必须为正整数。  
1074 * @param {String} key  消息的认证key,根据消息内容和应用Id计算出的key,应用通过审核后,可以在open.yy.com获取。  
1075 * @param {Array} textData  包含文字信息的数组,数组每个元素是json对象,示例如下。<br>
1076 * [{ text: "嘎嘎鱼", type: 2, userData: 87639876 }, { text: "邀请全部子频道的人一起玩", type: 1 }, { text: "猜骰子", type: 2, userData: 105620}]<br>
1077 * 数组中每个元素的格式:<br>
1078 * text: 文字信息<br>
1079 * type: 是普通文字还是链接文字,1=普通文字 2=链接文字 其他值无效<br>
1080 * userData: 如果是链接文字,userData保存链接自定义数据,是一个正整数,点击链接的时候可以得到此数据,如果是普通文字可以没有此属性<br>
1081 * @returns 返回调用是否成功,是一个Object对象,具体属性如下。<br/>
1082 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1083 * @type Object
1084 */
1085 IYYChannelAppMsg.prototype.sendMsgToSubChannelEx = function(subChannelId, token, key, textData) {
1086     if (arguments.length !== 4) return { ret: yy_e_api_param_error };
1087     if (typeof subChannelId !== "number" || typeof token !== "number" || typeof key !== "string" || !(textData instanceof Array)) return { ret: yy_e_api_param_error };
1088     if (isNaN(subChannelId) || isNaN(token)) return { ret: yy_e_api_param_error };
1089 
1090     var textString = "";
1091     var sp = "";
1092     for (var i = 0; i < textData.length; i++) {
1093         var dtString = "{";
1094         if (textData[i].text === null || textData[i].text === undefined || typeof textData[i].text !== "string") {
1095             return { ret: yy_e_api_param_error };
1096         }
1097         else {
1098             var msg = textData[i].text;
1099             msg = msg.replace(/\\/g, "\\\\"); //替换斜杠
1100             msg = msg.replace(/\"/g, "\\\""); //替换双引号
1101             dtString = dtString + "\"text\":\"" + msg + "\"";
1102         }
1103         if (textData[i].type === null || textData[i].type === undefined || typeof textData[i].type !== "number") {
1104             return { ret: yy_e_api_param_error };
1105         }
1106         else {
1107             dtString = dtString + ",\"type\":" + textData[i].type;
1108         }
1109         if (textData[i].userData === null || textData[i].userData === undefined) {
1110             if (textData[i].type === 2) return { ret: yy_e_api_param_error };
1111             dtString = dtString + "}";
1112         }
1113         else {
1114             if (typeof textData[i].userData !== "number") return { ret: yy_e_api_param_error };
1115             dtString = dtString + ",\"userData\":" + textData[i].userData + "}";
1116         }
1117 
1118         textString = textString + sp + dtString;
1119         sp = ",";
1120     }
1121     var result = callExternal("IChannelAppMsg_SendMsgToSubChannelEx", subChannelId, token, key, "[" + textString + "]");
1122     return result;
1123 };
1124 
1125 
1126 /**
1127 * 发送应用消息给指定用户。用户必须在同一大频道中,且必须在线才能收到。可以发送包含多个链接的消息。
1128 * @param {Array} userList 存有目标用户uid的数组。    
1129 * @param {Number} token  设置token,消息标记,必须为正整数。 
1130 * @param {String} key  消息的认证key,根据消息内容和应用Id计算出的key,应用通过审核后,可以在open.yy.com获取。 
1131 * @param {Array} textData  包含文字信息的数组,数组每个元素是json对象。格式同sendMsgToSubChannelEx。
1132 * @see #sendMsgToSubChannelEx
1133 * @returns 返回调用是否成功,是一个Object对象,具体属性如下。<br/>
1134 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1135 * @type Object
1136 */
1137 IYYChannelAppMsg.prototype.sendMsgToUsersEx = function(userList, token, key, textData) {
1138     if (arguments.length !== 4) return { ret: yy_e_api_param_error };
1139     if (!(userList instanceof Array) || typeof token !== "number" || typeof key !== "string" || !(textData instanceof Array)) return { ret: yy_e_api_param_error };
1140     if (isNaN(token)) return { ret: yy_e_api_param_error };
1141     var textString = "";
1142     var sp = "";
1143     for (var i = 0; i < textData.length; i++) {
1144         var dtString = "{";
1145         //----
1146         if (textData[i].text === null || textData[i].text === undefined || typeof textData[i].text !== "string") {
1147             return { ret: yy_e_api_param_error };
1148         }
1149         else {
1150             var msg = textData[i].text;
1151             msg = msg.replace(/\\/g, "\\\\"); //替换斜杠
1152             msg = msg.replace(/\"/g, "\\\""); //替换双引号
1153             dtString = dtString + "\"text\":\"" + msg + "\"";
1154         }
1155         //----
1156         if (textData[i].type === null || textData[i].type === undefined || typeof textData[i].type !== "number") {
1157             return { ret: yy_e_api_param_error };
1158         }
1159         else {
1160             dtString = dtString + ",\"type\":" + textData[i].type;
1161         }
1162         //----
1163         if (textData[i].userData === null || textData[i].userData === undefined) {
1164             if (textData[i].type === 2) return { ret: yy_e_api_param_error };
1165             dtString = dtString + "}";
1166         }
1167         else {
1168             if (typeof textData[i].userData !== "number") return { ret: yy_e_api_param_error };
1169             dtString = dtString + ",\"userData\":" + textData[i].userData + "}";
1170         }
1171 
1172         textString = textString + sp + dtString;
1173         sp = ",";
1174     }
1175 
1176     var result = callExternal("IChannelAppMsg_SendMsgToUsersEx", userList, token, key, "[" + textString + "]");
1177     return result;
1178 };
1179 
1180 /**
1181 * 应用消息链接点击事件。应用消息中的超链接被点击的时候会触发。
1182 * @field
1183 * @example
1184 * 侦听函数格式: function(eventData){    } 
1185 * 侦听函数参数说明: 
1186 * eventData.token: Number类型,发送消息的时候设置的token,可以用来判断哪一条消息被点击。
1187 * @example
1188 * 使用示例:
1189 * yy.channel.appMsg.addEventListener(IYYChannelAppMsg.APP_LINK_CLICKED,onLinkClicked);
1190 *
1191 * function onLinkClicked(eventData)
1192 * {
1193 *     document.getElementById("txtLog").innerHTML="消息的Token="+eventData.token;
1194 * }
1195 */
1196 IYYChannelAppMsg.APP_LINK_CLICKED = "YY_APP_LINK_CLICKED";
1197 
1198 /**
1199 * 应用消息链接点击事件。应用消息中的超链接被点击的时候会触发。
1200 * @field
1201 * @example
1202 * 侦听函数格式: function(eventData){    } 
1203 * 侦听函数参数说明: 
1204 * eventData.token: Number类型,发送消息的时候设置的token,可以用来判断哪一条消息被点击。
1205 * eventData.userData: Number类型,发送消息的时候链接里设置的userData值。
1206 * @example
1207 * 使用示例:
1208 * yy.channel.appMsg.addEventListener(IYYChannelAppMsg.APP_LINK_EX_CLICKED,onLinkExClicked);
1209 *
1210 * function onLinkExClicked(eventData)
1211 * {
1212 *     document.getElementById("txtLog").innerHTML="消息的Token="+eventData.token+" userData="+eventData.userData;
1213 * }
1214 */
1215 IYYChannelAppMsg.APP_LINK_EX_CLICKED = "YY_APP_LINK_EX_CLICKED";
1216 //-------------------------------IYYChannelChat-------------------------------
1217 
1218 /**
1219 * IYYChannelChat 构造函数。
1220 * @extends IYYCommon
1221 * @class 公屏聊天和私聊接口。接受公屏聊天消息和私聊消息。
1222 * @constructor
1223 */
1224 function IYYChannelChat() {
1225 };
1226 
1227 IYYChannelChat.prototype = new IYYCommon();
1228 
1229 /**
1230 * 在频道中收到公屏聊天消息。当有用户在公屏上输入聊天信息的时候会触发。
1231 * @field
1232 * @example
1233 * 侦听函数格式: function(eventData){    } 
1234 * 侦听函数参数说明: 
1235 * eventData.uid: Number类型,发送公屏消息的用户的uid。
1236 * eventData.msg: String类型,发送公屏消息的文字内容。
1237 * @example
1238 * 使用示例:
1239 * yy.channel.chat.addEventListener(IYYChannelChat.CHAT,onChannelChat);
1240 *
1241 * function onChannelChat(eventData)
1242 * {
1243 *     document.getElementById("txtLog").innerHTML="收到来自uid="+eventData.uid+"的公屏聊天消息msg="+eventData.msg;
1244 * }
1245 */
1246 IYYChannelChat.CHAT = "YY_CHANNEL_CHAT";
1247 
1248 /**
1249 * 在频道中收到私聊消息。当收到其他用户发送过来的私聊消息的时候触发。
1250 * @field
1251 * @example
1252 * 侦听函数格式: function(eventData){    } 
1253 * 侦听函数参数说明: 
1254 * eventData.uid: Number类型,发送私聊消息的用户的uid。
1255 * eventData.msg: String类型,发送私聊消息的文字内容。
1256 * @example
1257 * 使用示例:
1258 * yy.channel.chat.addEventListener(IYYChannelChat.CHAT_FROM,onChannelChatFrom);
1259 *
1260 * function onChannelChatFrom(eventData)
1261 * {
1262 *     document.getElementById("txtLog").innerHTML="收到来自uid="+eventData.uid+"的私聊消息msg="+eventData.msg;
1263 * }
1264 */
1265 IYYChannelChat.CHAT_FROM = "YY_CHANNEL_CHAT_FROM";
1266 //-------------------------------IYYReceptionChannel-------------------------------
1267 /**
1268 * IYYReceptionChannel 构造函数。
1269 * @extends IYYCommon
1270 * @class 接待频道接口,提供获取,设置,取消接待频道等功能。
1271 * @constructor
1272 */
1273 function IYYReceptionChannel() {
1274 };
1275 
1276 IYYReceptionChannel.prototype = new IYYCommon();
1277 
1278 
1279 /**
1280 * 设置接待频道。某些情况下需要等待几秒才生效。
1281 * @param {Number} cid 频道的长位id。
1282 * @returns 返回调用是否成功,是一个Object对象,具体属性如下。<br/>
1283 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1284 * @type Object
1285 */
1286 IYYReceptionChannel.prototype.setReceptionChannel = function(cid) {
1287     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
1288     if (typeof cid !== "number" || isNaN(cid)) return { ret: yy_e_api_param_error };
1289     var result = callExternal("IReceptionChannel_SetReceptionChannel", cid);
1290     return result;
1291 };
1292 
1293 /**
1294 * 获取接待频道。
1295 * @returns 返回接待频道信息,具体属性如下。<br/>
1296 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1297 * <b>cid</b>: Number类型 接待频道的长位Id。如果为0,表示当前没有设置接待频道<br/>
1298 * @type Object
1299 * @example 
1300 * 使用示例:
1301 * var result = yy.channel.receptionChannel.getReceptionChannel();
1302 * if(result.ret==0)
1303 * {
1304 *    if(result.cid==0)
1305 *    {
1306 *        document.getElementById("txtLog").innerHTML = "尚未设置接待频道";
1307 *    }
1308 *    else
1309 *    {
1310 *        document.getElementById("txtLog").innerHTML = "接待频道Id:" + result.cid;
1311 *    }
1312 * }
1313 *   
1314 * 成功的返回值示例:{ ret:0,cid:88995544}
1315 * 失败的返回值示例:{ ret:984832}
1316 
1317 */
1318 IYYReceptionChannel.prototype.getReceptionChannel = function () {
1319     var result = callExternal("IReceptionChannel_GetReceptionChannel");
1320     if (result.ret == 0) {
1321         return { ret: 0, cid: result.channel_id };
1322     }
1323     else {
1324         return result;
1325     }
1326 };
1327 /**
1328 * 反设置接待频道,移除接待频道。
1329 * @returns 返回调用是否成功,具体属性如下。<br/>
1330 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1331 * @type Object
1332 */
1333 IYYReceptionChannel.prototype.unSetReceptionChannel = function() {
1334     var result = callExternal("IReceptionChannel_UnSetReceptionChannel");
1335     return result;
1336 };
1337 
1338 
1339 //-------------------------------IYYChannelMicList-------------------------------
1340 /**
1341 * IYYChannelMicList 构造函数。
1342 * @extends IYYCommon
1343 * @class 麦序接口,提供麦序的信息和相关事件。
1344 
1345 * @constructor
1346 */
1347 function IYYChannelMicList() {
1348 };
1349 
1350 IYYChannelMicList.prototype = new IYYCommon();
1351 
1352 
1353 /**
1354 * 获取麦序用户列表。
1355 * @returns 返回麦序中所有用户的uid。<br/>
1356 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1357 * <b>micList</b>: Array类型 返回麦序中所有用户的uid,uid保存在一个数组中。<br/>
1358 * @type Object
1359 * @example 
1360 * 使用示例:
1361 * var result=yy.channel.micList.getMicList();
1362 * if(result.ret==0)
1363 * {
1364 *   document.getElementById("txtLog").innerHTML="在麦序中的用户为:"+result.micList;
1365 * }
1366 * 成功的返回值示例:{ ret:0,micList:[1234444,2234455,3311344]}
1367 * 失败的返回值示例:{ ret:984832}
1368 */
1369 IYYChannelMicList.prototype.getMicList = function() {
1370     var result = callExternal("IChannelMicList_GetMicList");
1371     if (result.ret === 0) {
1372         return { ret: 0, micList: result.mic_list.concat() };
1373     }
1374     else {
1375         return result;
1376     }
1377 };
1378 
1379 /**
1380 * 加入麦序。
1381 * @returns 返回调用是否成功,具体属性如下。<br/>
1382 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1383 * @type Object
1384 */
1385 IYYChannelMicList.prototype.joinMicList = function() {
1386     var result = callExternal("IChannelMicList_JoinMicList");
1387     return result;
1388 };
1389 /**
1390 * 离开麦序。
1391 * @returns 返回调用是否成功,具体属性如下。<br/>
1392 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1393 * @type Object
1394 */
1395 IYYChannelMicList.prototype.leaveMicList = function() {
1396     var result = callExternal("IChannelMicList_LeaveMicList");
1397     return result;
1398 };
1399 
1400 /**
1401 * 拉人上麦。需要的权限跟YY客户端一致。
1402 * @param {Number} uid 被拉用户的uid。    
1403 * @returns 返回调用是否成功,具体属性如下。<br/>
1404 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1405 * @type Object
1406 */
1407 IYYChannelMicList.prototype.pullUserToMicList = function(uid) {
1408     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
1409     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
1410     var result = callExternal("IChannelMicList_PullUserToMicList", uid);
1411     return result;
1412 };
1413 /**
1414 * 踢人下麦。需要的权限跟YY客户端一致。
1415 * @param {Number} uid 被踢用户的uid。  
1416 * @returns 返回调用是否成功,具体属性如下。<br/>
1417 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1418 * @type Object
1419 */
1420 IYYChannelMicList.prototype.kickMicListUser = function(uid) {
1421     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
1422     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
1423     var result = callExternal("IChannelMicList_KickMicListUser", uid);
1424     return result;
1425 };
1426 
1427 /**
1428 * 清空麦序。需要的权限跟YY客户端一致。
1429 * @returns 返回调用是否成功,具体属性如下。<br/>
1430 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1431 * @type Object
1432 */
1433 IYYChannelMicList.prototype.clearMicList = function() {
1434     var result = callExternal("IChannelMicList_ClearMicList");
1435     return result;
1436 };
1437 
1438 /**
1439 * 将用户调整到2号麦序。需要的权限跟YY客户端一致。
1440 * @param {Number} uid 被移动用户的uid。  
1441 * @returns 返回调用是否成功,具体属性如下。<br/>
1442 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1443 * @type Object
1444 */
1445 IYYChannelMicList.prototype.moveUserToTop = function(uid) {
1446     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
1447     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
1448     var result = callExternal("IChannelMicList_MoveUserToTop", uid);
1449     return result;
1450 };
1451 
1452 
1453 /**
1454 * 获取连麦用户列表。
1455 * @returns 返回连麦中的所有用户的uid。<br/>
1456 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1457 * <b>linkedMicList</b>: Array类型 uid保存在一个数组中。无人连麦时返回空数组。<br/>
1458 * @type Object
1459 * @example 
1460 * 使用示例:
1461 * var result=yy.channel.micList.linkedMicList();
1462 * if(result.ret==0)
1463 * {
1464 *   document.getElementById("txtLog").innerHTML="在连麦中的用户为:"+result.linkedMicList;
1465 * }
1466 * 成功的返回值示例:{ ret:0,linkedMicList:[1234444,2234455,3311344]}
1467 * 失败的返回值示例:{ ret:984832}
1468 */
1469 IYYChannelMicList.prototype.getLinkedMicList = function () {
1470     var result = callExternal("IChannelMicList_GetLinkedMicList");
1471     if (result.ret === 0) {
1472         return { ret: 0, linkedMicList: result.linked_mic_list.concat() };
1473     }
1474     else {
1475         return result;
1476     }
1477 };
1478 
1479 /**
1480 * 将用户加入到连麦列表。需要在麦序模式才有效,需要有频道管理员及以上权限才能调用成功。
1481 * @param {Number} uid 被连麦用户的uid。  
1482 * @returns 返回调用是否成功,具体属性如下。<br/>
1483 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1484 * @type Object
1485 */
1486 IYYChannelMicList.prototype.linkMicToTheQueueHead = function (uid) {
1487     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
1488     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
1489     var result = callExternal("IChannelMicList_LinkMicToTheQueueHead", uid);
1490     return result;
1491 };
1492 
1493 /**
1494 * 将用户移出连麦列表。需要在麦序模式才有效,需要有频道管理员及以上权限才能调用成功。
1495 * @param {Number} uid 移出连麦的用户的uid。  
1496 * @returns 返回调用是否成功,具体属性如下。<br/>
1497 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1498 * @type Object
1499 */
1500 IYYChannelMicList.prototype.removeFromLinkedMicList = function (uid) {
1501     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
1502     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
1503     var result = callExternal("IChannelMicList_RemoveFromLinkedMicList", uid);
1504     return result;
1505 };
1506 
1507 /**
1508 * 获得频道模式。
1509 * @returns 返回当前频道模式,具体属性如下。<br/>
1510 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1511 * <b>cid</b>: Number类型 返回频道模式 ,0=自由模式,1=主席模式,2=麦序模式<br/>
1512 * @type Object
1513 * @example 
1514 * 使用示例:
1515 * var result = yy.channel.micList.getMicListMode();
1516 * if(result.ret==0)
1517 * {
1518 *     document.getElementById("txtLog").innerHTML = "当前频道模式:" + result.mode;
1519 * }
1520 *   
1521 * 成功的返回值示例:{ ret:0,mode:2}
1522 * 失败的返回值示例:{ ret:984832}
1523 * @type Object
1524 */
1525 IYYChannelMicList.prototype.getMicListMode = function () {
1526     var result = callExternal("IChannelMicList_GetMicListMode");
1527     if (result.ret == 0) {
1528         return { ret: 0, mode: result.mode };
1529     } else {
1530         return result;
1531     }
1532 
1533 };
1534 /**
1535 * 设置频道模式。需要有管理员及以上权限,两次调用需要有一定的时间间隔。
1536 * @param {Number} mode 频道模式,0=自由模式,1=主席模式,2=麦序模式,其它值无效。  
1537 * @returns 返回调用是否成功,具体属性如下。<br/>
1538 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1539 * @type Object
1540 */
1541 IYYChannelMicList.prototype.setMicListMode = function (mode) {
1542     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
1543     if (typeof mode !== "number" || isNaN(mode)) return { ret: yy_e_api_param_error };
1544     var result = callExternal("IChannelMicList_SetMicListMode",mode);
1545     return result
1546 };
1547 
1548 /**
1549 * 将麦序上指定的用户上移一位。麦序模式下有效,需要有管理员及以上权限,规则和权限同YY客户端一致。
1550 * @param {Number} uid 被上移的用户uid。  
1551 * @returns 返回调用是否成功,具体属性如下。<br/>
1552 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1553 * @type Object
1554 */
1555 IYYChannelMicList.prototype.moveUpOnePosition = function (uid) {
1556     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
1557     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
1558     var result = callExternal("IChannelMicList_MoveUpOnePosition",uid);
1559     return result;
1560 };
1561 
1562 /**
1563 * 将麦序上指定的用户下移一位。麦序模式下有效,需要有管理员及以上权限,规则和权限同YY客户端一致。
1564 * @param {Number} uid 被下移的用户uid。  
1565 * @returns 返回调用是否成功,具体属性如下。<br/>
1566 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1567 * @type Object
1568 */
1569 IYYChannelMicList.prototype.moveDownOnePosition = function (uid) {
1570     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
1571     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
1572     var result = callExternal("IChannelMicList_MoveDownOnePosition",uid);
1573     return result;
1574 };
1575 
1576 /**
1577 * 获取麦首的麦序时间,返回为秒数。
1578 * @returns 返回麦首的麦序时间,具体属性如下。<br/>
1579 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1580 * <b>seconds</b>: Number类型 返回麦首的麦序剩余时间,单位为秒<br/>
1581 * @type Object
1582 * @example 
1583 * 使用示例:
1584 * var result = yy.channel.micList.getFirstMicSeconds();
1585 * if(result.ret==0)
1586 * {
1587 *     document.getElementById("txtLog").innerHTML = "麦首麦序时间剩余:" + result.seconds;
1588 * }
1589 *   
1590 * 成功的返回值示例:{ ret:0,seconds:248}
1591 * 失败的返回值示例:{ ret:984832}
1592 */
1593 IYYChannelMicList.prototype.getFirstMicSeconds = function () {
1594     var result = callExternal("IChannelMicList_GetFirstMicSeconds");
1595     if (result.ret == 0) {
1596         return { ret: 0, seconds: result.seconds };
1597     } else {
1598         return result;
1599     }
1600 };
1601 
1602 /**
1603 * 麦首麦序时间加倍。需要有管理员及以上权限,规则和权限同YY客户端一致。
1604 * @returns 返回调用是否成功,具体属性如下。<br/>
1605 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1606 * @type Object
1607 */
1608 IYYChannelMicList.prototype.doubleFirstMicSeconds = function () {
1609     var result = callExternal("IChannelMicList_DoubleFirstMicSeconds");
1610     return result;
1611 };
1612 
1613 /**
1614 * 开麦,即允许用户加入麦序。需要有管理员及以上权限,规则和权限同YY客户端一致。
1615 * @returns 返回调用是否成功,具体属性如下。<br/>
1616 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1617 * @type Object
1618 */
1619 IYYChannelMicList.prototype.enableJoinMicList = function () {
1620     var result = callExternal("IChannelMicList_EnableJoinMicList");
1621     return result;
1622 };
1623 
1624 /**
1625 * 禁麦,即禁止用户加入麦序。需要有管理员及以上权限,规则和权限同YY客户端一致。
1626 * @returns 返回调用是否成功,具体属性如下。<br/>
1627 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1628 * @type Object
1629 */
1630 IYYChannelMicList.prototype.disableJoinMicList = function () {
1631     var result = callExternal("IChannelMicList_DisableJoinMicList");
1632     return result;
1633 };
1634 
1635 /**
1636 * 控麦,即禁止麦首用户说话,麦序时间暂停,管理员除外。需要有管理员及以上权限,规则和权限同YY客户端一致。
1637 * @returns 返回调用是否成功,具体属性如下。<br/>
1638 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1639 * @type Object
1640 */
1641 IYYChannelMicList.prototype.controlMicList = function () {
1642     var result = callExternal("IChannelMicList_ControlMic");
1643     return result;
1644 };               
1645 /**
1646 * 放麦,即允许麦首用户说话,麦序时间继续。需要有管理员及以上权限,规则和权限同YY客户端一致。
1647 * @returns 返回调用是否成功,具体属性如下。<br/>
1648 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1649 * @type Object
1650 */
1651 IYYChannelMicList.prototype.releaseMicList = function () {
1652     var result = callExternal("IChannelMicList_ReleaseMic");
1653     return result;
1654 };
1655 
1656 /**
1657 * 查询当前是否是开麦状态。
1658 * @returns 返回开麦状态,具体属性如下。<br/>
1659 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1660 * <b>enabled</b>: Boolean类型 是否开麦,true=开麦,false=禁麦。<br/>
1661 * @type Object
1662 * @example 
1663 * 使用示例:
1664 * var result = yy.channel.micList.isJoinMicListEnabled();
1665 * if(result.ret==0)
1666 * {
1667 *     document.getElementById("txtLog").innerHTML = "麦首麦序时间剩余:" + result.enabled;
1668 * }
1669 *   
1670 * 成功的返回值示例:{ ret:0,enabled:true}
1671 * 失败的返回值示例:{ ret:984832}
1672 */
1673 IYYChannelMicList.prototype.isJoinMicListEnabled = function () {
1674     var result = callExternal("IChannelMicList_IsJoinMicListEnabled");
1675     if (result.ret == 0) {
1676         return { ret: 0, enabled: result.enabled };
1677     } else {
1678         return result;
1679     }
1680 };
1681 
1682 /**
1683 * 查询当前是否是控麦状态。
1684 * @returns 返回控麦状态,具体属性如下。<br/>
1685 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1686 * <b>controlled</b>: Boolean类型 当前是否控麦,true=控麦,false=放麦。<br/>
1687 * @type Object
1688 * @example 
1689 * 使用示例:
1690 * var result = yy.channel.micList.isMicListControlled();
1691 * if(result.ret==0)
1692 * {
1693 *     document.getElementById("txtLog").innerHTML = "麦首麦序时间剩余:" + result.controlled;
1694 * }
1695 *   
1696 * 成功的返回值示例:{ ret:0,controlled:true}
1697 * 失败的返回值示例:{ ret:984832}
1698 */
1699 IYYChannelMicList.prototype.isMicListControlled = function () {
1700     var result = callExternal("IChannelMicList_IsMicListControlled");
1701     if (result.ret == 0) {
1702         return { ret: 0, controlled: result.controlled };
1703     } else {
1704         return result;
1705     }
1706 };
1707 
1708 /**
1709 * 发送麦序提醒给2号麦用户,上麦后只能向用户发送一次。需要有管理员及以上权限,规则和权限同YY客户端一致。
1710 * @returns 返回调用是否成功,具体属性如下。<br/>
1711 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1712 * @type Object
1713 */
1714 IYYChannelMicList.prototype.sendMicListNotification = function () {
1715     var result = callExternal("IChannelMicList_SendMicListNotification");
1716     return result;
1717 };
1718 
1719 /**
1720 * 控麦事件。管理员控麦的时候触发。
1721 * @field
1722 * @example
1723 * 侦听函数格式: function(eventData){    } 
1724 * 侦听函数参数说明: 
1725 * eventData.adminUid: Number类型 执行控麦操作的管理员的uid。
1726 * @example
1727 * 使用示例:
1728 * yy.channel.micList.addEventListener(IYYChannelMicList.CONTROLLED,onMicControlled);
1729 *
1730 * function onMicControlled(eventData)
1731 * {
1732 *     document.getElementById("txtLog").innerHTML="管理员"+eventData.adminUid+"执行了控麦操作";
1733 * }
1734 */
1735 IYYChannelMicList.CONTROLLED = "YY_MICLIST_CONTROLLED";
1736 
1737 /**
1738 * 放麦事件。管理员放麦的时候触发。
1739 * @field
1740 * @example
1741 * 侦听函数格式: function(eventData){    } 
1742 * 侦听函数参数说明: 
1743 * eventData.adminUid: Number类型 执行放麦操作的管理员的uid。
1744 * @example
1745 * 使用示例:
1746 * yy.channel.micList.addEventListener(IYYChannelMicList.RELEASED,onMicReleased);
1747 *
1748 * function onMicReleased(eventData)
1749 * {
1750 *     document.getElementById("txtLog").innerHTML="管理员"+eventData.adminUid+"执行了放麦操作";
1751 * }
1752 */
1753 IYYChannelMicList.RELEASED = "YY_MICLIST_RELEASED";
1754 
1755 /**
1756 * 禁麦事件。管理员禁麦的时候触发。
1757 * @field
1758 * @example
1759 * 侦听函数格式: function(eventData){    } 
1760 * 侦听函数参数说明: 
1761 * eventData.adminUid: Number类型 执行禁麦操作的管理员的uid。
1762 * @example
1763 * 使用示例:
1764 * yy.channel.micList.addEventListener(IYYChannelMicList.DISABLE_JOIN,onMicDisableJoin);
1765 *
1766 * function onMicDisableJoin(eventData)
1767 * {
1768 *     document.getElementById("txtLog").innerHTML="管理员"+eventData.adminUid+"执行了禁麦操作";
1769 * }
1770 */
1771 IYYChannelMicList.DISABLE_JOIN = "YY_MICLIST_DISABLE_JOIN";
1772 
1773 /**
1774 * 开麦事件。管理员开麦的时候触发。
1775 * @field
1776 * @example
1777 * 侦听函数格式: function(eventData){    } 
1778 * 侦听函数参数说明: 
1779 * eventData.adminUid: Number类型 执行开麦操作的管理员的uid。
1780 * @example
1781 * 使用示例:
1782 * yy.channel.micList.addEventListener(IYYChannelMicList.ENABLE_JOIN,onMicEnableJoin);
1783 *
1784 * function onMicEnableJoin(eventData)
1785 * {
1786 *     document.getElementById("txtLog").innerHTML="管理员"+eventData.adminUid+"执行了开麦操作";
1787 * }
1788 */
1789 IYYChannelMicList.ENABLE_JOIN = "YY_MICLIST_ENABLE_JOIN";
1790 
1791 /**
1792 * 麦首麦序时间变化事件。管理员修改麦首麦序时间的时候触发。
1793 * @field
1794 * @example
1795 * 侦听函数格式: function(eventData){    } 
1796 * 侦听函数参数说明: 
1797 * eventData.adminUid: Number类型 执行麦序时间加倍操作的管理员的uid。
1798 * eventData.uid: Number类型 麦首的用户uid。
1799 * eventData.seconds: Number类型 变化后的麦序时间,单位为秒。
1800 * @example
1801 * 使用示例:
1802 * yy.channel.micList.addEventListener(IYYChannelMicList.TIME_CHANGED,onMicTimeChanged);
1803 *
1804 * function onMicTimeChanged(eventData)
1805 * {
1806 *     document.getElementById("txtLog").innerHTML="管理员"+eventData.adminUid+"修改麦首"+eventData.uid+"的麦序时间为"+eventData.seconds+"秒";
1807 * }
1808 */
1809 IYYChannelMicList.TIME_CHANGED = "YY_MICLIST_TIME_CHANGED";
1810 
1811 /**
1812 * 用户说话状态变化事件。用户开始说话和停止说话时会触发,同频道界面用户名前的绿点变化一致。
1813 * @field
1814 * @example
1815 * 侦听函数格式: function(eventData){    } 
1816 * 侦听函数参数说明: 
1817 * eventData.uid: Number类型 说话的用户uid。
1818 * eventData.speaking: Boolean类型 true=开始说话,false=停止说话
1819 * @example
1820 * 使用示例:
1821 * yy.channel.micList.addEventListener(IYYChannelMicList.SPEAKING_STATE_CHANGED,onSpeakingStateChanged);
1822 *
1823 * function onSpeakingStateChanged(eventData)
1824 * {
1825 *     document.getElementById("txtLog").innerHTML="用户"+eventData.uid+"说话状态:"+eventData.speaking;
1826 * }
1827 */
1828 IYYChannelMicList.SPEAKING_STATE_CHANGED = "YY_MICLIST_SPEAKING_STATE_CHANGED";
1829 
1830 /**
1831 * 收到麦序提醒事件。当处在麦序第二位的时候才能收到此事件。
1832 * @field
1833 * @example
1834 * 侦听函数格式: function(eventData){    } 
1835 * 侦听函数参数说明: 
1836 * eventData.adminUid: Number类型 发送提醒的管理员的uid。
1837 * @example
1838 * 使用示例:
1839 * yy.channel.micList.addEventListener(IYYChannelMicList.NOTIFICATION,onRecvNotification);
1840 *
1841 * function onRecvNotification(eventData)
1842 * {
1843 *     document.getElementById("txtLog").innerHTML="收到来自"+eventData.adminUid+"的麦序提醒";
1844 * }
1845 */
1846 IYYChannelMicList.NOTIFICATION = "YY_MICLIST_NOTIFICATION";
1847 
1848 
1849 /**
1850 * 麦序用户增加事件。当有用户加入到麦序时会触发。
1851 * @field
1852 * @example
1853 * 侦听函数格式: function(eventData){    } 
1854 * 侦听函数参数说明: 
1855 * eventData.uid: Number类型 加入的用户uid。
1856 * @example
1857 * 使用示例:
1858 * yy.channel.micList.addEventListener(IYYChannelMicList.USER_JOIN,onUserJoin);
1859 *
1860 * function onUserJoin(eventData)
1861 * {
1862 *     document.getElementById("txtLog").innerHTML="用户"+eventData.uid+"加入到了麦序中";
1863 * }
1864 */
1865 IYYChannelMicList.USER_JOIN = "YY_MICLIST_USER_JOIN";
1866 
1867 
1868 /**
1869 * 麦序用户离开事件。当有用户离开麦序时会触发。
1870 * @field
1871 * @example
1872 * 侦听函数格式: function(eventData){    } 
1873 * 侦听函数参数说明: 
1874 * eventData.uid: Number类型 离开的用户uid。
1875 * @example
1876 * 使用示例:
1877 * yy.channel.micList.addEventListener(IYYChannelMicList.USER_LEAVE,onUserLeave);
1878 *
1879 * function onUserLeave(eventData)
1880 * {
1881 *     document.getElementById("txtLog").innerHTML="用户"+eventData.uid+"离开麦序了";
1882 * }
1883 */
1884 IYYChannelMicList.USER_LEAVE = "YY_MICLIST_USER_LEAVE";
1885 
1886 
1887 /**
1888 * 麦序用户移动事件。麦序用户发生位置调整的时候会触发。
1889 * @field
1890 * @example
1891 * 侦听函数格式: function(eventData){    } 
1892 * 侦听函数参数说明: 
1893 * eventData.moveId: Number类型 麦序中发生移动的用户uid。
1894 * eventData.toAfterId: Number类型 移动到哪个用户后面,用户无法移动到第一个。   
1895 * @example
1896 * 使用示例:
1897 * yy.channel.micList.addEventListener(IYYChannelMicList.USER_MOVE,onUserMove);
1898 *
1899 * function onUserMove(eventData)
1900 * {
1901 *     document.getElementById("txtLog").innerHTML="用户"+eventData.uid+"移动到"+eventData.toAfterId+"后面";
1902 * }
1903 */
1904 IYYChannelMicList.USER_MOVE = "YY_MICLIST_USER_MOVE";
1905 
1906 
1907 /**
1908 * 麦序用户清除事件。麦序用户全部被清除的时候会触发。
1909 * @field
1910 * @example
1911 * 侦听函数格式: function(){    } 
1912 * @example
1913 * 使用示例:
1914 * yy.channel.micList.addEventListener(IYYChannelMicList.CLEAR,onUserClear);
1915 *
1916 * function onUserClear()
1917 * {
1918 *     document.getElementById("txtLog").innerHTML="麦序用户被清除";
1919 * }
1920 */
1921 IYYChannelMicList.CLEAR = "YY_MICLIST_CLEAR";
1922 
1923 /**
1924 * 用户加入连麦列表事件。当有新的用户连麦的时候触发。
1925 * @field
1926 * @example
1927 * 侦听函数格式: function(eventData){    } 
1928 * 侦听函数参数说明: 
1929 * eventData.uid: Number类型 新加入连麦的用户uid。
1930 * @example
1931 * 使用示例:
1932 * yy.channel.micList.addEventListener(IYYChannelMicList.USER_LINKED,onUserLinked);
1933 *
1934 * function onUserLinked(eventData)
1935 * {
1936 *     document.getElementById("txtLog").innerHTML="用户"+eventData.uid+"加入连麦";
1937 * }
1938 */
1939 IYYChannelMicList.USER_LINKED = "YY_MICLIST_USER_MIC_LINKED";
1940 
1941 
1942 /**
1943 * 用户移出连麦列表事件。当有用户移出连麦的时候触发。
1944 * @field
1945 * @example
1946 * 侦听函数格式: function(eventData){    } 
1947 * 侦听函数参数说明: 
1948 * eventData.uid: Number类型 被移出连麦的用户uid。
1949 * @example
1950 * 使用示例:
1951 * yy.channel.micList.addEventListener(IYYChannelMicList.USER_UNLINKED,onUserUnlinked);
1952 *
1953 * function onUserUnlinked(eventData)
1954 * {
1955 *     document.getElementById("txtLog").innerHTML="用户"+eventData.uid+"移出连麦";
1956 * }
1957 */
1958 IYYChannelMicList.USER_UNLINKED = "YY_MICLIST_USER_MIC_UNLINKED";
1959 
1960 /**
1961 * 频道模式变化事件。当频道模式发生变化的时候触发。
1962 * @field
1963 * @example
1964 * 侦听函数格式: function(eventData){    } 
1965 * 侦听函数参数说明: 
1966 * eventData.mode: Number类型 当前的频道模式 0=自由模式,1=主席模式,2=麦序模式。
1967 * @example
1968 * 使用示例: 
1969 * yy.channel.micList.addEventListener(IYYChannelMicList.MODE_CHANGED,onModeChanged);
1970 *
1971 * function onModeChanged(eventData)
1972 * {
1973 *     document.getElementById("txtLog").innerHTML="当前频道模式="+eventData.mode;
1974 * }
1975 */
1976 IYYChannelMicList.MODE_CHANGED = "YY_MICLIST_MODE_CHANGE";
1977 //-------------------------------IYYChannelUserController-------------------------------
1978 /**
1979 * IYYChannelUserController 构造函数。
1980 * @extends IYYCommon
1981 * @class 频道用户控制接口。
1982 * @constructor
1983 */
1984 function IYYChannelUserController() {
1985 
1986 };
1987 
1988 IYYChannelUserController.prototype = new IYYCommon();
1989 
1990 /**
1991 * 允许频道用户文字聊天。权限规则和disableMsg方法相同。
1992 * @see #disableMsg
1993 * @param {Number} uid 用户的唯一标识id,即uid,<b>不是YY号</b> 。
1994 * @returns 返回调用是否成功,具体属性如下。<br/>
1995 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
1996 * @type Object
1997 */
1998 IYYChannelUserController.prototype.enableMsg = function(uid) {
1999     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2000     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
2001     var result = callExternal("IChannelUserController_EnableMsg", uid);
2002     return result;
2003 };
2004 
2005 /**
2006 * 禁止频道用户文字聊天。
2007 * 权限规则如下<br>
2008 * OW:可以允许和禁止频道内任何其他成员语音,文字。包括(VP MA CA CA2 R VIP G U)。<br>
2009 * VP:可以允许和禁止频道内任何其他成员语音,文字。 除了(OW,VP)。<br>
2010 * MA:可以允许和禁止频道内任何其他成员语音,文字。 除了(OW,VP,MA)。<br>
2011 * CA:可以允许和禁止相对应有管理权限的子频道内的语音,文字。包括( CA2 R VIP G U)。<br>
2012 * CA2:可以允许和禁止相对应有管理权限的子频道内的语音,文字。包括( R VIP G U)。<br>
2013 * R VIP G U 均无任何权限操作。<br>
2014 * 字母代表的意义如下:<br>
2015 * 游客(U),临时嘉宾(G),嘉宾(VIP),会员(R),二级子频道管理员(CA2),子频道管理员(CA),全频道管理员(MA),频道总管理(VP),频道所有者(OW)
2016 * @param {Number} uid 用户的唯一标识id,即uid,<b>不是YY号</b> 。
2017 * @returns 返回调用是否成功,具体属性如下。<br/>
2018 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2019 * @type Object
2020 * @see #enableMsg
2021 */
2022 IYYChannelUserController.prototype.disableMsg = function(uid) {
2023     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2024     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
2025     var result = callExternal("IChannelUserController_DisableMsg", uid);
2026     return result;
2027 };
2028 /**
2029 * 允许频道用户语音聊天。权限规则和disableMsg方法相同。
2030 * @see #disableMsg
2031 * @param {Number} uid 用户的唯一标识id,即uid,<b>不是YY号</b> 。
2032 * @returns 返回调用是否成功,具体属性如下。<br/>
2033 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2034 * @type Object
2035 */
2036 IYYChannelUserController.prototype.enableSpeak = function(uid) {
2037     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2038     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
2039     var result = callExternal("IChannelUserController_EnableSpeak", uid);
2040     return result;
2041 };
2042 /**
2043 * 禁止频道用户语音聊天。权限规则和disableMsg方法相同。
2044 * @see #disableMsg
2045 * @param {Number} uid 用户的唯一标识id,即uid,<b>不是YY号</b> 。
2046 * @returns 返回调用是否成功,具体属性如下。<br/>
2047 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2048 * @type Object
2049 */
2050 IYYChannelUserController.prototype.disableSpeak = function(uid) {
2051     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2052     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
2053     var result = callExternal("IChannelUserController_DisableSpeak", uid);
2054     return result;
2055 };
2056 /**
2057 * 查询指定用户是否允许文字聊天。
2058 * @param {Number} uid 被查询的用户的唯一标识id,即uid,<b>不是YY号</b> 。
2059 * @returns 返回查询结果,具体属性如下。<br/>
2060 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2061 * <b>enabled</b>: Boolean类型 true=用户允许文字聊天,false=用户已被禁止文字聊天。<br/>
2062 * @type Object
2063 * @example 
2064 * 使用示例:
2065 * var result = yy.channel.userController.isMsgEnabled(435345);
2066 * if(result.ret==0)
2067 * {
2068 *     document.getElementById("txtLog").innerHTML = result.enabled?"用户可以文字聊天": "用户被禁止文字聊天";
2069 * }
2070 *   
2071 * 成功的返回值示例:{ ret:0,enabled:true}
2072 * 失败的返回值示例:{ ret:984832}
2073 */
2074 IYYChannelUserController.prototype.isMsgEnabled = function (uid) {
2075     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2076     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
2077     var result = callExternal("IChannelUserController_IsMsgEnabled", uid);
2078     if (result.ret == 0) {
2079         return { ret: 0, enabled: result.enabled };
2080     }
2081     else {
2082         return result;
2083     }
2084 };
2085 /**
2086 * 查询指定用户是否允许语音聊天。
2087 * @param {Number} uid 被查询的用户的唯一标识id,即uid,<b>不是YY号</b> 。
2088 * @returns 返回查询结果,具体属性如下。<br/>
2089 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2090 * <b>enabled</b>: Boolean类型 true=用户允许语音聊天,false=用户已被禁止语音聊天。<br/>
2091 * @type Object
2092 * @example 
2093 * 使用示例:
2094 * var result = yy.channel.userController.isSpeakEnabled(435345);
2095 * if(result.ret==0)
2096 * {
2097 *     document.getElementById("txtLog").innerHTML = result.enabled?"用户可以语音聊天": "用户被禁止语音聊天";
2098 * }
2099 *   
2100 * 成功的返回值示例:{ ret:0,enabled:true}
2101 * 失败的返回值示例:{ ret:984832}
2102 */
2103 IYYChannelUserController.prototype.isSpeakEnabled = function (uid) {
2104     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2105     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
2106     var result = callExternal("IChannelUserController_IsSpeakEnabled", uid);
2107     if (result.ret == 0) {
2108         return { ret: 0, enabled: result.enabled };
2109     }
2110     else {
2111         return result;
2112     }
2113 };
2114 /**
2115 * 进子频道。
2116 * @param {Number} cid 子频道长位id,必须是在当前大频道中的一个频道。 
2117 * @returns 返回调用是否成功,具体属性如下。<br/>
2118 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2119 * @type Object
2120 */
2121 IYYChannelUserController.prototype.jumpToSubChannel = function(cid) {
2122     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2123     if (typeof cid !== "number" || isNaN(cid)) return { ret: yy_e_api_param_error };
2124     var result = callExternal("IChannelUserController_JumpToSubChannel", cid);
2125     return result;
2126 };
2127 /**
2128 * 拉人进子频道。<br>
2129 * 权限规则如下<br>
2130 * OW:可以调度频道内任何成员,包括(VP MA CA CA2 R VIP G U)。<br>
2131 * VP:可以调度频道内除OW以外的任何成员,包括(VP MA CA1 CA2 R VIP G U)。<br>
2132 * MA:可以调度频道内除了OW,VP以外的任何成员,包括(MA CA CA2 R VIP G U)。<br>
2133 * CA:可以调度相对应有管理权限的1级子频道内的成员,(OW,VP,MA)除外。<br>
2134 * CA2:可以调度相对应有管理权限的2级子频道内的成员,(OW,VP,MA,CA1)除外。<br>
2135 * R VIP G U 均无任何权限操作。<br>
2136 * 字母代表的意义如下:<br>
2137 * 游客(U),临时嘉宾(G),嘉宾(VIP),会员(R),二级子频道管理员(CA2),子频道管理员(CA),全频道管理员(MA),频道总管理(VP),频道所有者(OW)<br>
2138 * @param {Number} uid 被拉的用户的uid。
2139 * @param {Number} cid 子频道长位id,必须是当前大频道中的一个频道。 
2140 * @returns 返回调用是否成功,具体属性如下。<br/>
2141 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2142 * @type Object
2143 */
2144 IYYChannelUserController.prototype.pullToSubChannel = function(uid, cid) {
2145     if (arguments.length !== 2) return { ret: yy_e_api_param_error };
2146     if (typeof cid !== "number" || typeof uid !== "number" || isNaN(uid) || isNaN(cid)) return { ret: yy_e_api_param_error };
2147     var result = callExternal("IChannelUserController_PullToSubChannel", uid, cid);
2148     return result;
2149 };
2150 
2151 /**
2152 * 获取用户所在子频道ID。该用户必须在当前大频道中。
2153 * @returns 返回用户所在的频道信息,具体属性如下。<br/>
2154 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2155 * <b>cid</b>: Number类型 用户所在子频道长位Id<br/>
2156 * @type Object
2157 * @example 
2158 * 使用示例:
2159 * var result = yy.channel.userController.getUserSubChannelId(435345);
2160 * if(result.ret==0)
2161 * {
2162 *     document.getElementById("txtLog").innerHTML = "用户当前在" + result.cid+"频道";
2163 * }
2164 *   
2165 * 成功的返回值示例:{ ret:0,cid:88548884}
2166 * 失败的返回值示例:{ ret:984832}
2167 */
2168 IYYChannelUserController.prototype.getUserSubChannelId = function(uid) {
2169     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2170     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
2171     var result = callExternal("IChannelUserController_GetUserSubChannelId", uid);
2172     if (result.ret === 0) {
2173         return { ret: 0, cid: result.cid };
2174     }
2175     else {
2176         return result;
2177     }
2178 
2179 };
2180 
2181 /**
2182 * 设置马甲。发起设置用户和被设置用户必须同时在线且在同一个大频道,发起者需要有管理员马甲,具体规则和权限同YY客户端一致。
2183 * @param {Number} cid 用户所在的频道id。如果用户在子频道,需要传子频道id。
2184 * @param {Number} uid 用户的uid。 
2185 * @param {Number} role 用户的角色(马甲)数值。可以设置的马甲的数值如下:  <br>
2186 *   游客(U)  白马 25 <br>
2187 *   临时嘉宾(G) 浅绿色马甲 66 <br>
2188 *   嘉宾(VIP)  绿马 88 <br>
2189 *   会员(R)  蓝马 100 <br>
2190 *   二级子频道管理员(CA2)  粉马 150 <br>
2191 *   子频道管理员(CA) 红马 175 <br>
2192 *   全频道管理员(MA)  黄马 200 <br>
2193 *   频道总管理(VP) 橙马 230 <br>
2194 * @returns 返回调用是否成功,具体属性如下。<br/>
2195 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2196 * @type Object
2197 */
2198 IYYChannelUserController.prototype.setUserRole = function(cid, uid, role) {
2199     if (arguments.length !== 3) return { ret: yy_e_api_param_error };
2200     if (typeof uid !== "number" || isNaN(uid) || typeof cid !== "number" || isNaN(cid) || typeof role !== "number" || isNaN(role)) return { ret: yy_e_api_param_error };
2201     var result = callExternal("IChannelUserController_SetUserRole", cid, uid, role);
2202     return result;
2203 };
2204 //-------------------------------IYYChannelUserListPopMenu-------------------------------
2205 /**
2206 * IYYChannelUserListPopMenu 构造函数。
2207 * @extends IYYCommon
2208 * @class 频道右键菜单接口。频道用户列表右键菜单设置和取消, 和对应的菜单事件设置 。
2209 * @constructor
2210 */
2211 function IYYChannelUserListPopMenu() {
2212 
2213 };
2214 
2215 IYYChannelUserListPopMenu.prototype = new IYYCommon();
2216 
2217 
2218 /**
2219 * 设置大频道用户列表右键菜单,可以增加一个菜单项,一个应用只可以增加一个菜单项。
2220 * @param {String} menuText 菜单上的文字,字符串最大长度20字节。
2221 * @returns 返回调用是否成功,具体属性如下。<br/>
2222 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2223 * @type Object
2224 */
2225 IYYChannelUserListPopMenu.prototype.setPopMenu = function(menuText) {
2226     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2227     if (typeof menuText !== "string") return { ret: yy_e_api_param_error };
2228     menuText = menuText.replace(/\\/g, "\\\\"); //替换斜杠
2229     menuText = menuText.replace(/\"/g, "\\\""); //替换双引号    
2230     var result = callExternal("IChannelUserListPopMenu_SetPopMenu", menuText);
2231     return result;
2232 };
2233 
2234 
2235 /**
2236 * 去掉右键菜单增加项。
2237 * @returns 返回调用是否成功,具体属性如下。<br/>
2238 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2239 * @type Object
2240 */
2241 IYYChannelUserListPopMenu.prototype.unSetPopMenu = function() {
2242     var result = callExternal("IChannelUserListPopMenu_UnSetPopMenu");
2243     return result;
2244 };
2245 
2246 
2247 /**
2248 * 用户点击菜单项事件。当用户列表右键菜单项被点击的时候会触发。
2249 * @field
2250 * @example
2251 * 侦听函数格式: function(eventData){    } 
2252 * eventData.uid: Number类型 被选中的用户的uid。
2253 * eventData.cid: Number类型 当前的频道长位id。    
2254 * @example
2255 * 使用示例:
2256 * yy.channel.userListPopMenu.addEventListener(IYYChannelUserListPopMenu.CLICKED,onClicked);
2257 *
2258 * function onClicked(eventData)
2259 * {
2260 *     document.getElementById("txtLog").innerHTML="用户"+eventData.uid+"菜单被点击,当前频道"+eventData.cid;
2261 * }
2262 */
2263 
2264 IYYChannelUserListPopMenu.CLICKED = "YY_POP_MENU_CLICKED";
2265 
2266 //-------------------------------IYYChannelTabPage-------------------------------
2267 /**
2268 * IYYChannelTabPage 构造函数。
2269 * @extends IYYCommon
2270 * @class 频道tab页控制接口 。
2271 * @constructor
2272 */
2273 function IYYChannelTabPage() {
2274 
2275 };
2276 
2277 IYYChannelTabPage.prototype = new IYYCommon();
2278 /**
2279 * 显示应用所在的tabpage窗口。
2280 * @returns 返回调用是否成功,具体属性如下。<br/>
2281 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2282 * @type Object
2283 */
2284 IYYChannelTabPage.prototype.selectTabPage = function() {
2285     var result = callExternal("IChannelTabPage_SelectTabPage");
2286     return result;
2287 };
2288 //-------------------------------IYYCloud-----------------------------
2289 
2290 /**
2291 * IYYCloud 构造函数。
2292 * @extends IYYCommon
2293 * @class 简单存储接口。提供简单的简单存储数据服务,包括增,删,改,查的基本操作,除了 频道所有者(OW紫马)和 频道总管理(VP橙马)可以删除和修改所有数据之外,其他用户只能删除和修改自己的数据,每个用户都可以查询所有数据。
2294 * @constructor
2295 */
2296 function IYYCloud() {
2297 
2298 };
2299 
2300 
2301 IYYCloud.prototype = new IYYCommon();
2302 
2303 //----------常量----------
2304 
2305 
2306 
2307 /**
2308 * 增加数据。<b>注意:同一个用户在一个应用中两次保存之间需要间隔1秒</b>。
2309 * @param {Number} int1 要保存的数据,32位无符号整数,范围[0,4294967295],超出范围返回错误码12。 
2310 * @param {Number} int2 要保存的数据,32位无符号整数,范围[0,4294967295],超出范围返回错误码12。 
2311 * @param {String} str 要保存的数据。    
2312 * @returns 返回调用是否成功,是一个Object对象,具体属性如下<br/>
2313 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2314 * <b>key</b>: String类型 返回码 增加成功后返回数据的key。key可以唯一标识一条数据<br/>
2315 * @example 
2316 * var result=yy.cloud.addData(11,22,"hello yy");
2317 * if(result.ret==0)
2318 * {
2319 *     document.getElementById("txtLog").innerHTML=result.ret;
2320 * }
2321 * 成功时返回数据key值和返回码0,例如 {ret:0,key:"000000004f55d48f"}。
2322 * 失败时返回错误代码,例如{"ret":5}
2323 * @type Object
2324 */
2325 IYYCloud.prototype.addData = function(int1, int2, str) {
2326     if (arguments.length === 0 || arguments.length > 3) return { ret: yy_e_api_param_error };
2327     if (typeof int1 !== "number" || typeof int2 !== "number" || typeof str !== "string" || isNaN(int1) || isNaN(int2)) return { ret: yy_e_api_param_error };
2328     str = str.replace(/\\/g, "\\\\"); //替换斜杠
2329     str = str.replace(/\"/g, "\\\""); //替换双引号
2330     var result;
2331     switch (arguments.length) {
2332         case 1:
2333             result= callExternal("ICloud_AddData", 0, 0, arguments[0]);
2334             break;
2335         case 2:
2336             result= callExternal("ICloud_AddData", arguments[0], 0, arguments[1]);
2337             break;
2338         case 3:
2339             result= callExternal("ICloud_AddData", arguments[0], arguments[1], arguments[2]);
2340             break;
2341         default:
2342     }
2343     if (result.ret == 0) {
2344         return { ret: 0, key: result.key };
2345     } else {
2346         return result;
2347     }
2348 };
2349 
2350 
2351 /**
2352 * 修改数据。
2353 * @param {Number} int1 被修改的数据的新值,32位无符号整数,范围[0,4294967295],超出范围返回错误码12。 
2354 * @param {Number} int2 被修改的数据的新值,32位无符号整数,范围[0,4294967295],超出范围返回错误码12。 
2355 * @param {String} str 被修改的数据的新值。          
2356 * @param {Array} filter 过滤器数组,保存YYCloudFilter对象数组,找到要修改的数据。
2357 * @returns 返回调用是否成功,具体属性如下。<br/>
2358 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2359 * @type Object
2360 * @see YYCloudFilter
2361 */
2362 IYYCloud.prototype.updateData = function(int1, int2, str, filter) {
2363     if (arguments.length !== 4) return { ret: yy_e_api_param_error };
2364     if (typeof int1 !== "number" || typeof int2 !== "number" || typeof str !== "string" || !(filter instanceof Array) || isNaN(int1) || isNaN(int2)) return { ret: yy_e_api_param_error };
2365     var filterString = "";
2366     var sp = "";
2367     str = str.replace(/\\/g, "\\\\"); //替换斜杠
2368     str = str.replace(/\"/g, "\\\""); //替换双引号
2369     for (var i = 0; i < filter.length; i++) {
2370         filterString = filterString + sp + filter[i].toString();
2371         sp = ",";
2372     }
2373     var result = callExternal("ICloud_UpdateData", int1, int2, str, filterString);
2374     return result;
2375 };
2376 
2377 
2378 /**
2379 * 删除数据。
2380 * @param {Array} filter 过滤器数组,即删除的条件。保存YYCloudFilter对象数组。  
2381 * @returns 返回调用是否成功,具体属性如下。<br/>
2382 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2383 * @type Object
2384 * @see YYCloudFilter
2385 */
2386 IYYCloud.prototype.deleteData = function(filter) {
2387     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2388     if (!(filter instanceof Array)) return { ret: yy_e_api_param_error };
2389     var filterString = "";
2390     var sp = "";
2391     for (var i = 0; i < filter.length; i++) {
2392         filterString = filterString + sp + filter[i].toString();
2393         sp = ",";
2394     }
2395     var result = callExternal("ICloud_DeleteData", filterString);
2396     return result;
2397 };
2398 
2399 
2400 
2401 
2402 
2403 /**
2404 * 查询数据。
2405 * @param {Array} filter 过滤器数组,查询的条件。数组中为YYCloudFilter对象。没有查到数据或查询出错时返回空数组。    
2406 * @returns 返回查询结果,是一个Object对象,具体属性如下<br/>
2407 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2408 * <b>data</b>: Array类型 查询结果,保存在数组中。数组的元素为Object对象。<br/>
2409 * 每个数据的属性如下:<br/>
2410 * <b>key</b>: String类型 数据的键值。<br/>
2411 * <b>createTime</b>: String类型 数据创建的时间。<br/>
2412 * <b>updateTime</b>: String类型 数据更新的时间。<br/>
2413 * <b>creatorUid</b>: Number类型 数据创建者的uid。<br/>
2414 * <b>intValue1</b>: Number类型 int字段数据,32位无符号整数,范围[0,4294967295]。<br/>
2415 * <b>intValue2</b>: Number类型 int字段数据,32位无符号整数,范围[0,4294967295]。<br/>
2416 * <b>stringValue</b>: String类型 string字段数据。<br/>
2417 * @example 
2418 * //查询某一时间段内的数据
2419 * var dt = new Date();
2420 * var filterTime = new YYCloudFilter();
2421 * filterTime.field = YYCloudFilter.EField.CREATE_TIME;
2422 * filterTime.op = YYCloudFilter.EFilterOperator.GREATER;
2423 * filterTime.value = Math.ceil(dt.getTime() / 1000 - 600);
2424 * filterTime.condition = YYCloudFilter.EFilterCondition.NONE;
2425 * var result = yy.cloud.queryData([filterTime]);
2426 * if(result.ret==0)
2427 * {
2428 *     document.getElementById("txtLog").innerHTML="查询到数据个数:"+result.data.length;
2429 * }
2430 * 成功时返回数据,示例如下
2431 *{ret:0,data:[
2432 *  {key:"4f55d3d7",createTime:"2012-03-06 17:07:35",updateTime:"2012-03-06 17:07:35",creatorUid:1710881282,intValue1:1,intValue2:100,stringValue:"你好,简单存储!hello cloud"},
2433 *  {key:"4f55d48f",createTime:"2012-03-06 17:10:39",updateTime:"2012-03-06 17:10:39",creatorUid:1710881282,intValue1:1,intValue2:100,stringValue:"可存可取"},
2434 *  {key:"4f55d57d",createTime:"2012-03-06 17:14:37",updateTime:"2012-03-06 17:14:37",creatorUid:1710881282,intValue1:1,intValue2:100,stringValue:"this is test"}
2435 *]} 
2436 * 成功时但没有查询到数据,格式如下* {"ret":0,"data":[]}
2437 * 失败时返回错误代码,例如{"ret":5}
2438 * @type Object
2439 * @see YYCloudFilter
2440 */
2441 IYYCloud.prototype.queryData = function(filter) {
2442     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2443     if (!(filter instanceof Array)) return { ret: yy_e_api_param_error };
2444     var filterString = "";
2445     var sp = "";
2446     for (var i = 0; i < filter.length; i++) {
2447         filterString = filterString + sp + filter[i].toString();
2448         sp = ",";
2449     }
2450     var result = callExternal("ICloud_QueryData", filterString);
2451     if (result.ret === 0) {
2452         return { ret: 0, data: parseCloudDataList(result.data) };
2453     }
2454     else {
2455 
2456         return result;
2457     }
2458 };
2459 //-----------------------------------IYYFinance---------------------------
2460 
2461 /**
2462 * IYYFinance 构造函数
2463 * @extends IYYCommon
2464 * @class 财务接口。提供Y币扣费请求和赠送开放平台礼物接口。
2465 * @constructor
2466 */
2467 function IYYFinance() {
2468 };
2469 
2470 IYYFinance.prototype = new IYYCommon();
2471 
2472 
2473 /**
2474 * 发送扣费请求。某些参数需要从应用服务器获取。
2475 * @param {String} sn 请求流水号,从您的应用服务器获取,请参考open.yy.com上文档中心的支付流程介绍。
2476 * @param {Number} serverId 您的应用服务器的Id,您可以有多个应用服务器,请参考open.yy.com上文档中心的支付流程介绍。
2477 * @param {Number} money 扣费数量,最小单位为0.01Y币,也就是1分钱。 例如 参数100表示付费1Y币。
2478 * @param {Number} moneyType 目前10表示Y币 未来会支持其他种类货币。
2479 * @param {String} token 该次消费请求的token,从应用服务器获取,请参考open.yy.com上文档中心的支付流程介绍。
2480 * @param {Number} mode 调用的方式,0=真实扣费,1=测试扣费,其他值无效。测试时连接测试支付服务器。
2481 * @returns 返回调用是否成功,具体属性如下。<br/>
2482 * <b>ret</b>: Number类型 返回码 0=发送请求成功,仅仅表示发送请求成功,不表示扣费成功,非0值参考错误代码。是否扣费成功请参考IYYFinance.BUY_RESPONSE事件。<br/>
2483 * @type Object 
2484 */
2485 IYYFinance.prototype.buy = function (sn, serverId, money, moneyType, token, mode) {
2486     if (arguments.length < 5 || arguments.length > 6) return { ret: yy_e_api_param_error };
2487     if (typeof sn !== "string" || typeof serverId !== "number" || typeof money !== "number" || typeof moneyType !== "number" || typeof token !== "string") return { ret: yy_e_api_param_error };
2488     if (mode === null || mode === undefined || mode === void 0) mode = 0;
2489     //yytrace("SDK:"+money + "  " + Math.floor(money));
2490     //if (money != Math.floor(money)) return { ret: yy_e_api_param_error };
2491     //老版本用老接口,新版本用新接口
2492     yytrace("yyversion:"+(yy.version.majorVersion * 100 + yy.version.minorVersion));
2493     if ((yy.version.majorVersion * 100 + yy.version.minorVersion) < 113) {
2494         var result = callExternal("IFinance_Buy", sn, serverId, money, moneyType, token, mode);
2495         return result;
2496     }
2497     else {
2498         return yy.finance.buyByYuan(sn, serverId, money / 100, moneyType, token, mode);
2499     }
2500 };
2501 /**
2502 * 以元为单位发送扣费请求。某些参数需要从应用服务器获取。
2503 * @param {String} sn 请求流水号,从您的应用服务器获取,请参考open.yy.com上文档中心的支付流程介绍。
2504 * @param {Number} serverId 您的应用服务器的Id,您可以有多个应用服务器,请参考open.yy.com上文档中心的支付流程介绍。
2505 * @param {Number} money 扣费数量,最小单位为0.01Y币,也就是1分钱。 <b>例如 参数1.14表示付费1.14Y币。</b>
2506 * @param {Number} moneyType 目前10表示Y币 未来会支持其他种类货币。
2507 * @param {String} token 该次消费请求的token,从应用服务器获取,请参考open.yy.com上文档中心的支付流程介绍。
2508 * @param {Number} mode 调用的方式,0=真实扣费,1=测试扣费,其他值无效。测试时连接测试支付服务器。
2509 * @returns 返回调用是否成功,具体属性如下。<br/>
2510 * <b>ret</b>: Number类型 返回码 0=发送请求成功,仅仅表示发送请求成功,不表示扣费成功,非0值参考错误代码。是否扣费成功请参考IYYFinance.BUY_RESPONSE事件。<br/>
2511 * @type Object 
2512 */
2513 IYYFinance.prototype.buyByYuan = function (sn, serverId, money, moneyType, token, mode) {
2514     //if ((money * 100) != Math.floor(money * 100)) return { ret: yy_e_api_param_error };
2515     if (arguments.length < 5 || arguments.length > 6) return { ret: yy_e_api_param_error };
2516     if (typeof sn !== "string" || typeof serverId !== "number" || typeof money !== "number" || typeof moneyType !== "number" || typeof token !== "string") return { ret: yy_e_api_param_error };
2517     if (mode === null || mode === undefined || mode === void 0) mode = 0;
2518     var result = callExternal("IFinance_BuyByYuan", sn, serverId, money, moneyType, token, mode);
2519     return result;
2520 };
2521 /**
2522 * 发送赠送礼物请求。某些参数需要从应用服务器获取。
2523 * @param {String} sn 请求流水号,从您的应用服务器获取,请参考open.yy.com上文档中心的支付流程介绍。
2524 * @param {Number} serverId 您的应用服务器的Id,您可以有多个应用服务器,请参考open.yy.com上文档中心的支付流程介绍。
2525 * @param {Number} toUid 礼物接受者的uid,如果自己购买则填0。
2526 * @param {Number} giftId 赠送礼物的Id。
2527 * @param {Number} giftCount 赠送礼物的数量。
2528 * @param {Number} moneyType 目前10表示Y币 未来会支持其他种类货币。
2529 * @param {String} token 该次消费请求的token,从应用服务器获取,请参考open.yy.com上的支付流程介绍。
2530 * @param {Number} mode 调用的方式,0=真实赠送,1=测试赠送,其他值无效。测试时连接测试支付服务器。
2531 * @returns 仅仅表示发送请求成功,不表示扣费成功,0=发送请求成功,非0值参考错误代码。是否扣费成功请参考IYYFinance.BUY_GIFTS_RESPONSE事件。
2532 * @type Object 
2533 */
2534 IYYFinance.prototype.buyGifts = function (sn, serverId, toUid, giftId, giftCount, moneyType, token, mode) {
2535     if (arguments.length < 7 || arguments.length > 8) return { ret: yy_e_api_param_error };
2536     if (typeof toUid !== "number" || typeof sn !== "string" || typeof serverId !== "number" || typeof giftId !== "number" || typeof giftCount !== "number" || typeof moneyType !== "number" || typeof token !== "string") return { ret: yy_e_api_param_error };
2537     if (mode === null || mode === undefined || mode === void 0) mode = 0;
2538     var result = callExternal("IFinance_BuyGifts", toUid, sn, serverId, giftId, giftCount, moneyType, token, mode);
2539     return result;
2540 };
2541 
2542 /**
2543 * 弹出充值Y币的页面。
2544 * @returns 返回调用是否成功,具体属性如下。<br/>
2545 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2546 * @type Object
2547 */
2548 IYYFinance.prototype.recharge=function()
2549 {
2550 	var result = callExternal("IFinance_Recharge");
2551     return result;
2552 };
2553 
2554 
2555 
2556 /**
2557 * 扣费的响应事件。发送扣费请求后服务器返回结果时会触发此事件。
2558 * @field
2559 * @example
2560 * 侦听函数格式: function(eventData){    } 
2561 * eventData.sn: String类型 请求流水号。
2562 * eventData.mode: Number类型 0=真实扣费,1=测试扣费。
2563 * eventData.ret: Number类型 请求的结果。数值代表意义为:
2564 * 1=正常处理 20=等待用户确认,可能会弹窗 25=非法token 3=该应用不允许扣费 -32=该用户Y币+佣金总额不足 255=失败,原因未知
2565 
2566 * @example
2567 * 使用示例:
2568 * yy.finance.addEventListener(IYYFinance.BUY_RESPONSE,onBuyResponse);
2569 *
2570 * function onBuyResponse(eventData)
2571 * {
2572 *     document.getElementById("txtLog").innerHTML="流水号:"+eventData.sn+" 结果:"+eventData.ret+" 模式:"+eventData.mode;
2573 * }
2574 */
2575 IYYFinance.BUY_RESPONSE = "YY_BUY_RESPONSE";
2576 
2577 /**
2578 * 赠送开放平台礼物的响应事件。发送赠送礼物请求后服务器返回结果时会触发此事件。
2579 * @field
2580 * @example
2581 * 侦听函数格式: function(eventData){    } 
2582 * eventData.sn: String类型 请求流水号。
2583 * eventData.mode: Number类型 0=真实扣费,1=测试扣费。
2584 * eventData.ret: Number类型 请求的结果。数值代表意义为:
2585 * 1=正常处理 20=等待用户确认,可能会弹窗 25=非法token 3=该应用不允许扣费 -32=该用户Y币+佣金总额不足 255=失败,原因未知
2586 * @example
2587 * 使用示例:
2588 * yy.finance.addEventListener(IYYFinance.BUY_GIFTS_RESPONSE,onBuyGiftsResponse);
2589 *
2590 * function onBuyGiftsResponse(eventData)
2591 * {
2592 *     document.getElementById("txtLog").innerHTML="流水号:"+eventData.sn+" 结果:"+eventData.ret+" 模式:"+eventData.mode;
2593 * }
2594 */
2595 IYYFinance.BUY_GIFTS_RESPONSE = "YY_BUY_GIFTS_RESPONSE";
2596 
2597 //-----------------------------------IYYIM---------------------------
2598 /**
2599 * IYYIM 构造函数
2600 * @extends IYYCommon
2601 * @class 聊天接口。提供弹出聊天对话框,弹出添加好友对话框等功能。
2602 * @constructor
2603 */
2604 function IYYIM() {
2605 };
2606 
2607 IYYIM.prototype = new IYYCommon();
2608 
2609 
2610 /**
2611 * 给指定用户发送聊天消息, 调用后会弹出聊天对话框,需要用户点击确认才发送。
2612 * @param {Number} uid 用户的唯一标识id,即uid,<b>不是YY号</b> 。
2613 * @param {String} msg 等待发送的聊天的内容,最大长度40个字节。
2614 * @returns 返回调用是否成功,具体属性如下。<br/>
2615 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2616 * @type Object 
2617 */
2618 IYYIM.prototype.chatTo = function(uid, msg) {
2619     if (arguments.length !== 2) return { ret: yy_e_api_param_error };
2620     if (typeof uid !== "number" || isNaN(uid) || typeof msg !== "string") return { ret: yy_e_api_param_error };
2621     msg = msg.replace(/\\/g, "\\\\"); //替换斜杠
2622     msg = msg.replace(/\"/g, "\\\""); //替换双引号
2623     var result = callExternal("IIM_ChatTo", uid, msg);
2624     return result;
2625 };
2626 
2627 
2628 /**
2629 * 判断指定的用户是否是好友。
2630 * @param {Number} uid 指定用户的唯一标识id,即uid,<b>不是YY号</b> 。
2631 * @returns 返回是否是好友,具体属性如下。<br/>
2632 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2633 * <b>isFriend</b>: Boolean类型 是否是好友 ,true=是好友 false=不是好友<br/>
2634 * @type Object
2635 * @example 
2636 * 使用示例:
2637 * var result = yy.im.isFriend(3454365);
2638 * if(result.ret==0)
2639 * {
2640 *     document.getElementById("txtLog").innerHTML = "和用户3454365关系:" + result.isFriend?"好友:"非好友";
2641 * }
2642 *   
2643 * 成功的返回值示例:{ ret:0,isFriend:true}
2644 * 失败的返回值示例:{ ret:984832}
2645 */
2646 IYYIM.prototype.isFriend = function(uid) {
2647     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2648     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
2649     var result = callExternal("IIM_IsFriend", uid);
2650     if (result.ret === 0) {
2651         return { ret: 0, isFriend: result.is_friend };
2652     }
2653     else {
2654         return result;
2655     }
2656 };
2657 
2658 
2659 /**
2660 * 弹出添加好友对话框,用户确认才开始添加。
2661 * @param {Number} uid 用户的唯一标识id,即uid,<b>不是YY号</b> 。
2662 * @returns 返回调用是否成功,具体属性如下。<br/>
2663 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2664 * @type Object
2665 */
2666 IYYIM.prototype.addFriend = function(uid) {
2667     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2668     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
2669     var result = callExternal("IIM_AddFriend", uid);
2670     return result;
2671 };
2672 
2673 /**
2674 * 获取我所有好友的uid信息。
2675 * @returns 返回所有好友的uid,具体属性如下。<br/>
2676 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2677 * <b>buddyList</b>: Array类型 所有好友的uid ,uid保存在一个数组中 ,没有好友返回空数组<br/>
2678 * @type Object
2679 * @example 
2680 * 使用示例:
2681 * var result = yy.im.getAllBuddyList();
2682 * if(result.ret==0)
2683 * {
2684 *     document.getElementById("txtLog").innerHTML = "我的好友个数:" + result.buddyList.length;
2685 *     document.getElementById("txtLog").innerHTML = "<br/>我的好友为:" + result.buddyList;
2686 * }
2687 *   
2688 * 成功的返回值示例:{ ret:0,isFriend:true}
2689 * 失败的返回值示例:{ ret:984832}
2690 
2691 */
2692 IYYIM.prototype.getAllBuddyList = function () {
2693     var result = callExternal("IIM_GetAllBuddyList");
2694     if (result.ret == 0) {
2695         return { ret: 0, buddyList: result.list };
2696     }
2697     else {
2698         return result;
2699     }
2700 };
2701 
2702 /**
2703 * 获取我指定的好友的详细信息。目前只能返回uid,YY号和昵称这三个信息。好友不在线也可以取到信息。
2704 * @param {Number} uid 要查询的好友的uid。
2705 * @returns 返回好友的信息,是Object对象,具体属性如下。<br/>
2706 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2707 * <b>uid</b>: Number类型 好友的uid<br/>
2708 * <b>imId</b>: Number类型 好友的YY号<br/>
2709 * <b>name</b>: String类型 好友的昵称<br/>
2710 * @type Object
2711 * @example 
2712 * 使用示例:
2713 * var result = yy.im.getIMUserInfo(43465465);
2714 * if(result.ret==0)
2715 * {
2716 *     document.getElementById("txtLog").innerHTML = "好友的uid:" + result.uid;
2717 *     document.getElementById("txtLog").innerHTML = "<br/>好友的昵称:" + result.name;
2718 *     document.getElementById("txtLog").innerHTML = "<br/>好友的YY号:" + result.imId;
2719 * }
2720 *   
2721 * 成功的返回值示例:{ ret:0,uid:12345678,imId:987654321,name:"美羊羊"} 
2722 * 失败的返回值示例:{ ret:984832}
2723 */
2724 IYYIM.prototype.getIMUserInfo = function (uid) {
2725     if (arguments.length !== 1) return null;
2726     if (typeof uid !== "number" || isNaN(uid)) return null;
2727     var result = callExternal("IIM_GetIMUserInfo", uid);
2728     if (result.ret === 0) {
2729         return { ret: 0, uid: result.uid, imId: result.imid, name: unescape(result.nick_name) };
2730     }
2731     else {
2732         return result;
2733     }
2734 };
2735 //------------------------------IYYInteraction------------------------------
2736 /**
2737 * IYYInteraction 构造函数。
2738 * @extends IYYCommon
2739 * @class 应用互动接口。能够提供邀请者的信息。
2740 * @constructor
2741 */
2742 function IYYInteraction() {
2743 }
2744 IYYInteraction.prototype = new IYYCommon();
2745 
2746 /**
2747 * 获取邀请者uid,只有在被邀请启动应用才能获取成功。
2748 * @returns 邀请者信息,是一个Object对象,具体属性如下。<br/>
2749 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2750 * <b>inviterUid</b>: Number类型 邀请者的uid,如果没有邀请者inviterUid=0 <br/>
2751 * @type Object
2752 * @example 
2753 * 使用示例:
2754 * var result = yy.interaction.getInviter();
2755 * if (result.inviterUid == 0) {
2756 *     document.getElementById("txtLog").innerHTML = "没有邀请者";
2757 * } else {
2758 *     document.getElementById("txtLog").innerHTML = "邀请者uid=" + result.inviterUid;
2759 * }
2760 * 成功的返回值示例:{ ret:0,inviterUid:435345} ,{ ret:0,inviterUid:0}
2761 * 失败的返回值示例:{ ret:984832}
2762 */
2763 IYYInteraction.prototype.getInviter = function () {
2764     var result = callExternal("IInteraction_GetInviter");
2765     if (result.ret == 0) {
2766         return { ret: 0, inviterUid: result.inviter_id };
2767     }
2768     else {
2769         return result;
2770     }
2771 };
2772 
2773 /**
2774 * 发送邀请。可以邀请当前所在子频道的所有人或者邀请指定用户。
2775 * @param {Number} inviteType 邀请的类型,1=邀请子频道所有人(子频道人数大于50调用无效),2=邀请指定用户(将会打开窗口来选择用户列表),其他值无效。
2776 * @returns 返回调用是否成功,具体属性如下。<br/>
2777 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2778 * @type Object
2779 */
2780 IYYInteraction.prototype.invite = function (inviteType) {
2781     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2782     if (inviteType === 1 || inviteType === 2) {
2783         var result = callExternal("IInteraction_Invite", inviteType);
2784         return result;
2785     }
2786     else {
2787         return { ret: yy_e_api_param_error };
2788     }
2789 };
2790 /**
2791 * 获取应用交互启动参数。当应用通过网页的链接或者应用消息启动时,可以获取启动时设置的参数。
2792 * @returns 返回参数信息,是一个Object对象,具体属性如下。
2793 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2794 * <b>runParams</b>: String类型 启动参数信息 <br/>
2795 * @example 
2796 * 使用示例:
2797 * var result=yy.interaction.getRunParams();
2798 * if(result.ret==0)
2799 * {
2800 *     document.getElementById("txtLog").innerHTML = "启动参数=" + result.runParams;
2801 * }
2802 * <b>通过应用消息启动应用</b>:
2803 * 返回启动参数的格式为{ret:0,runParams:"{\"cookie\":8888,\"user_data\":0}"},其中cookie的值是在发送应用消息的时候设置的token值。
2804 * 
2805 *
2806 * <b>通过应用飞机票或者网页链接启动应用</b>:
2807 * 典型飞机票链接格式如下yy://pd-[sid=43670710&appid=100901&userData=hellobabby] 
2808 * 其中sid是频道id,appid是应用id,userData就是启动参数,是一个字符串。
2809 * 示例的应用飞机票返回的启动参数为{ret:0,runParams:"hellobabby"}
2810 *
2811 * <b>通过其他方式启动应用</b>
2812 * 返回空字符串。{ret:0,runParams:""}
2813 * @type String
2814 */
2815 IYYInteraction.prototype.getRunParams = function () {
2816     var result = callExternal("IInteraction_GetRunParams");
2817     if (result.ret === 0) {
2818         return { ret: 0, runParams: result.run_params };
2819     }
2820     else {
2821         return result;
2822     }
2823 };
2824 
2825 /**
2826 * 生成当前应用的飞机票。
2827 * @param {Number} subChannelId 应用所在子频道的长位id。
2828 * @param {Boolean} isJump 运行飞机票时是否跳频道,如果false表示本频道有应用的话,不跳频道。
2829 * @returns 返回参数信息,是一个Object对象,具体属性如下。
2830 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2831 * <b>appTicket</b>: String类型 飞机票信息 <br/>
2832 * @type Object
2833 * @example 
2834 * 使用示例:
2835 * var result = yy.interaction.createAppTicket(478555775,false);
2836 * if (result.ret == 0) {
2837 *     document.getElementById("txtLog").innerHTML = "飞机票信息:"+result.appTicket;
2838 * }
2839 * 成功的返回值示例:{ ret:0,appTicket:"yy://open-[sid=43671710&appid=114369&appn=SDK测试&uid=249267551&mid=0352292]/[SDK测试]"}
2840 * 失败的返回值示例:{ ret:984832}
2841 */
2842 IYYInteraction.prototype.createAppTicket = function (subChannelId, isJump) {
2843     var result = callExternal("IInteraction_CreateAppTicket", subChannelId, isJump);
2844     if (result.ret === 0) {
2845         return { ret: 0, appTicket: result.app_ticket };
2846     }
2847     else {
2848         return result;
2849     }
2850 };
2851 
2852 
2853 //------------------------------IYYNet------------------------------
2854 /**
2855 * IYYNet 构造函数。
2856 * @extends IYYCommon
2857 * @class 网络通讯接口。提供广播数据和接收广播数据的功能。
2858 * @constructor
2859 */
2860 function IYYNet() {
2861 
2862 };
2863 
2864 IYYNet.prototype = new IYYCommon();
2865 
2866 /**
2867 * 子频道数据广播,包括自己。<b>两次广播需要间隔20毫秒,否则广播数据可能会丢失。</b>
2868 * @param {Number} sub_channel_id 子频道的长位id。
2869 * @param {String} data 要广播的数据,最大长度2048个字节。
2870 * @returns 返回调用是否成功,具体属性如下。<br/>
2871 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2872 * @type Object
2873 */
2874 IYYNet.prototype.broadcastSubChannel = function(sub_channel_id, data) {
2875     if (arguments.length !== 2) return { ret: yy_e_api_param_error };
2876     if (typeof sub_channel_id !== "number" || isNaN(sub_channel_id) || typeof data !== "string") return { ret: yy_e_api_param_error };
2877     var result = callExternal("INet_BroadCastSubChannel", sub_channel_id, encodeURI(data));
2878     return result;
2879 };
2880 
2881 /**
2882 * 全频道数据广播,包括自己。<b>两次广播需要间隔20毫秒,否则广播数据可能会丢失。</b>
2883 * @param {String} data 要广播的数据。最大长度2048个字节。
2884 * @returns 返回调用是否成功,具体属性如下。<br/>
2885 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2886 * @type Object
2887 */
2888 IYYNet.prototype.broadcastAllChannel = function(data) {
2889     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
2890     if (typeof data !== "string") return { ret: yy_e_api_param_error };
2891     var result = callExternal("INet_BroadCastAllChannel", encodeURI(data));
2892     return result;
2893 };
2894 
2895 /**
2896 * 广播给指定用户。<b>两次广播需要间隔20毫秒,否则广播数据可能会丢失。</b>
2897 * @param {Array} u_array 接收广播的用户uid,保存在一个数组中,用户个数必须小于等于100。 
2898 * @param {String} data 要广播的数据。最大长度2048个字节。  
2899 * @returns 返回调用是否成功,具体属性如下。<br/>
2900 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2901 * @type Object
2902 */
2903 IYYNet.prototype.broadcastToUsers = function(data, u_array) {
2904     if (arguments.length !== 2) return { ret: yy_e_api_param_error };
2905     if (typeof data !== "string" || !(u_array instanceof Array)) return { ret: yy_e_api_param_error };
2906     var result = callExternal("INet_BroadCastToUsers", encodeURI(data), u_array);
2907     return result;
2908 };
2909 
2910 /**
2911 * 收到频道广播消息事件。 收到广播消息后触发此事件。
2912 * @field
2913 * @example
2914 * 侦听函数格式: function(eventData){    } 
2915 * eventData.data: String类型  接收到的数据。
2916 * @example
2917 * 使用示例:
2918 * yy.net.addEventListener(IYYNet.RECV,onRecv);
2919 *
2920 * function onRecv(eventData)
2921 * {
2922 *     document.getElementById("txtLog").innerHTML="接收到"+eventData.data;
2923 * }
2924 */
2925 IYYNet.RECV = "YY_RECV";
2926 
2927 /**
2928 * 收到网络断开事件。点击关闭应用按钮的时候会触发,收到此消息2秒后,应用会被关闭。
2929 * @field
2930 * @example
2931 * 侦听函数格式: function(eventData){    } 
2932 * eventData.result: Number类型  基于何种原因断开了连接,请参考错误代码。result=983064时表示点击了关闭应用按钮,即将断开连接;
2933 * @example
2934 * 使用示例:
2935 * yy.net.addEventListener(IYYNet.CLOSED,onClosed);
2936 *
2937 * function onClosed(eventData)
2938 * {
2939 *     document.getElementById("txtLog").innerHTML="关闭原因:"+eventData.result;
2940 * }
2941 */
2942 IYYNet.CLOSED = "YY_NET_CLOSED";
2943 
2944 
2945 //------------------------------IYYSecurity------------------------------
2946 /**
2947 * IYYSecurity 构造函数。
2948 * @extends IYYCommon
2949 * @class 安全接口。提供获取安全认证信息等功能。
2950 */
2951 function IYYSecurity() {
2952 
2953 };
2954 
2955 
2956 IYYSecurity.prototype = new IYYCommon();
2957 /**
2958 * 获取当前用户安全认证令牌。
2959 * @returns 返回令牌字符信息,是一个Object对象,具体属性如下。<br/>
2960 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2961 * <b>token</b>: Number类型 令牌字符<br/>
2962 * @type Object
2963 * @example 
2964 * 使用示例:
2965 * var result = yy.security.getToken();
2966 * if (result.ret == 0) {
2967 *   document.getElementById("txtLog").innerHTML = "token="+result.token;
2968 * }
2969 * else
2970 * {
2971 *   document.getElementById("txtLog").innerHTML ="无法得到Token,错误码ret="+result.ret;
2972 * }
2973 * 成功的返回值示例:{ ret:0,token:"b9b8b4e4d0e107b3c7bd74bc48a6e28f0b1a0d61"}
2974 * 失败的返回值示例:{ ret:984832}
2975 */
2976 IYYSecurity.prototype.getToken = function () {
2977     var result = callExternal("ISecurity_GetToken");
2978     if (result.ret === 0) {
2979         return { ret: 0, token: result.token };
2980     }
2981     else {
2982         return result;
2983     }
2984 };
2985 
2986 /**
2987 * 进行举报。当发现需要举报内容时,调用此Api会弹出举报窗口。
2988 * @returns 返回调用是否成功,具体属性如下。<br/>
2989 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
2990 * @type Object
2991 */
2992 IYYSecurity.prototype.reportAbuse = function() {
2993     var result = callExternal("ISecurity_ReportAbuse");
2994     return result;
2995 };
2996 
2997 /**
2998 * 截屏进行举报。当发现需要举报内容时,调用此Api会弹出举报窗口。
2999 * @returns 返回调用是否成功,具体属性如下。<br/>
3000 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3001 * @type Object
3002 */
3003 IYYSecurity.prototype.reportScreenshot = function () {
3004     var result = callExternal("ISecurity_ReportScreenshot");
3005     return result;
3006 };
3007 
3008 
3009 /**
3010 * 敏感词检查。检查字符串中是否包含敏感词。
3011 * @param {String} words 等待检查的字符串。
3012 * @returns 返回是否包含敏感词,是一个Object对象,具体属性如下。<br/>
3013 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3014 * <b>pass</b>: Boolean类型 true=检查通过,不包含敏感词,false=包含敏感词<br/>
3015 * @type Object
3016 * @example 
3017 * 使用示例:
3018 * var result = yy.security.keywordFilter("Hello");
3019 * if (result.ret == 0) {
3020 *   document.getElementById("txtLog").innerHTML = result.pass?"不包含敏感词":"含有敏感词";
3021 * }
3022 * else
3023 * {
3024 *   document.getElementById("txtLog").innerHTML ="无法检查,错误码ret="+result.ret;
3025 * }
3026 * 成功的返回值示例:{ ret:0,pass:true}
3027 * 失败的返回值示例:{ ret:984832}
3028 */
3029 IYYSecurity.prototype.keywordFilter = function (words) {
3030     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
3031     if (typeof words !== "string") return { ret: yy_e_api_param_error };
3032     var result = callExternal("ISecurity_KeywordFilter",words);
3033     if (result.ret == 0) {
3034         return { ret: 0, pass: result.pass };
3035     } else {
3036         return result;
3037     }
3038 };
3039 //------------------------------IYYTempAudioSession------------------------------
3040 /**
3041 * IYYTempAudioSession 构造函数。
3042 * @extends IYYCommon
3043 * @class 临时语音接口。提供创建房间、加入房间、离开房间以及在房间语音聊天的功能.通过此接口可以跟其他用户建立临时语音聊天通道。<b>注意:用户同一时刻只能在一个房间进行语音聊天</b>
3044 * <b>所以在同一个YY上面,同一时刻,最多只有一个应用在使用临时语音。</b>
3045 */
3046 function IYYTempAudioSession() {
3047 }
3048 
3049 IYYTempAudioSession.prototype = new IYYCommon();
3050 /**
3051 * 创建一个临时语音房间。创建后用户自动进入该房间。在应用的生命周期内,同一个用户只能创建一个房间,第二次调用此函数会返回已经创建的房间的rid。房间中能够发言的人数有限,先要先得,目前暂定为5人。
3052 * @returns 返回创建的房间的rid,是一个Object对象,具体属性如下。<br/>
3053 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3054 * <b>rid</b>: Number类型 创建的房间的id<br/>
3055 * @type Object
3056 * @example 
3057 * 使用示例:
3058 * var result = yy.tempAudioSession.createRoom();
3059 * if (result.ret == 0) {
3060 *   document.getElementById("txtLog").innerHTML = "创建房间成功 rid="+result.rid;
3061 * }
3062 * else
3063 * {
3064 *   document.getElementById("txtLog").innerHTML ="创建房间失败,错误码ret="+result.ret;
3065 * }
3066 * 成功的返回值示例:{ ret:0,rid:3445566}
3067 * 失败的返回值示例:{ ret:984832}
3068 */
3069 IYYTempAudioSession.prototype.createRoom = function() {
3070     var result = callExternal("ITempAudioSession_CreateRoom");
3071     if (result.ret === 0) {
3072         return { ret: 0, rid: result.room_id };
3073     }
3074     else {
3075         return result;
3076     }
3077 };
3078 /**
3079 * 进入一个房间。刚进入时,能听到其他人的语音,但自己暂时不能发言。如果已经在某个房间中,需要调用leaveRoom退出这个房间调用,才能进入另外一个房间。
3080 * @param {Number} rid 要进入的房间的rid。
3081 * @returns 返回调用是否成功,具体属性如下。<br/>
3082 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3083 * @type Object
3084 * @see #leaveRoom
3085 */
3086 IYYTempAudioSession.prototype.enterRoom = function(rid) {
3087     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
3088     if (isNaN(rid) || typeof rid !== "number") return { ret: yy_e_api_param_error };
3089     var result = callExternal("ITempAudioSession_EnterRoom", rid);
3090     return result;
3091 };
3092 /**
3093 * 离开房间。如果房间人数为0,服务器过一段时间后会销毁这个房间。
3094 * @returns 返回调用是否成功,具体属性如下。<br/>
3095 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3096 * @type Object
3097 */
3098 IYYTempAudioSession.prototype.leaveRoom = function() {
3099     var result = callExternal("ITempAudioSession_LeaveRoom");
3100     return result;
3101 };
3102 /**
3103 * 开始语音聊天。调用成功后,自己可以在房间中发言。
3104 * @returns 返回调用是否成功,具体属性如下。<br/>
3105 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3106 * @type Object
3107 */
3108 IYYTempAudioSession.prototype.startSpeak = function() {
3109     var result = callExternal("ITempAudioSession_StartSpeak");
3110     return result;
3111 };
3112 /**
3113 * 禁止语音聊天。调用成功后,自己不能在房间中发言。
3114 * @returns 返回调用是否成功,具体属性如下。<br/>
3115 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3116 * @type Object
3117 */
3118 IYYTempAudioSession.prototype.stopSpeak = function() {
3119     var result = callExternal("ITempAudioSession_StopSpeak");
3120     return result;
3121 };
3122 
3123 /**
3124 * 设置临时语音房间音量。
3125 * @param {Number} vol  0至100的整数,0为静音。房间创建后,初始音量是100。
3126 * @returns 返回调用是否成功,具体属性如下。<br/>
3127 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3128 * @type Object
3129 */
3130 IYYTempAudioSession.prototype.setVolume = function(vol) {
3131     var result = callExternal("ITempAudioSession_SetVolume",vol);
3132     return result;
3133 };
3134 
3135 /**
3136 * 获取临时语音房间音量。
3137 * @returns 返回临时语音房间音量,是一个Object对象,具体属性如下。<br/>
3138 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3139 * <b>volume</b>: Number类型 返回[0,100]的整数,房间创建后,初始音量是100。<br/>
3140 * @type Object
3141 * @example 
3142 * 使用示例:
3143 * var result = yy.tempAudioSession.getVolume();
3144 * if (result.ret == 0) {
3145 *   document.getElementById("txtLog").innerHTML = "当前房间的音量 volume="+result.volume;
3146 * }
3147 * else
3148 * {
3149 *   document.getElementById("txtLog").innerHTML ="无法获取音量,错误码ret="+result.ret;
3150 * }
3151 * 成功的返回值示例:{ ret:0,volume:100}
3152 * 失败的返回值示例:{ ret:36866}
3153 */
3154 IYYTempAudioSession.prototype.getVolume = function () {
3155     var result = callExternal("ITempAudioSession_GetVolume");
3156     if (result.ret == 0) {
3157         return { ret: 0, volume: result.volume };
3158     } else {
3159         return result;
3160     }
3161 };
3162 
3163 /**
3164 * 正在使用临时语音的应用的AppId,可以用来查询临时语音的占用情况。一个YY上同时只能有一个应用在使用临时语音。
3165 * @returns 返回占用临时语音的应用的AppId信息,是一个Object对象,具体属性如下。<br/>
3166 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3167 * <b>ownerAppId</b>: Number类型 占用临时语音的应用的AppId。如果值为0表示没有应用在占用。<br/>
3168 * @type Object
3169 * @example 
3170 * 使用示例:
3171 * var result = yy.tempAudioSession.getOwner();
3172 * if (result.ret == 0) {
3173 *   document.getElementById("txtLog").innerHTML =(result.ownerAppId==0)?"没有应用在使用": "正在使用临时语音的应用AppId= "+result.ownerAppId;
3174 * }
3175 * 成功的返回值示例:{ ret:0,ownerAppId:100901}
3176 * 失败的返回值示例:{ ret:984832}
3177 */
3178 IYYTempAudioSession.prototype.getOwner = function() {
3179     var result = callExternal("ITempAudioSession_GetOwner");
3180     if (result.ret == 0) {
3181         return { ret: 0, ownerAppId: result.owner };
3182     } else {
3183         return result;
3184     }
3185 };
3186 /**
3187 * 用户进入房间事件。
3188 * @field
3189 * @example
3190 * 侦听函数格式: function(eventData){    } 
3191 * eventData.rid: Number类型  进入的房间的rid。
3192 * eventData.uid: Number类型  进入房间的用户的uid。
3193 * @example
3194 * 使用示例:
3195 * yy.tempAudioSession.addEventListener(IYYTempAudioSession.USER_ENTER_ROOM,onUserEnterRoom);
3196 *
3197 * function onUserEnterRoom(eventData)
3198 * {
3199 *     document.getElementById("txtLog").innerHTML="用户"+eventData.uid+"进入了房间"+eventData.rid;
3200 * }
3201 */
3202 IYYTempAudioSession.USER_ENTER_ROOM = "YY_TEMP_AUDIO_SESSION_USER_ENTER";
3203 
3204 /**
3205 * 用户离开房间事件。
3206 * @field
3207 * @example
3208 * 侦听函数格式: function(eventData){    } 
3209 * eventData.rid: Number类型  离开的房间的rid。
3210 * eventData.uid: Number类型  离开房间的用户的uid。
3211 * @example
3212 * 使用示例:
3213 * yy.tempAudioSession.addEventListener(IYYTempAudioSession.USER_LEAVE_ROOM,onUserLeaveRoom);
3214 *
3215 * function onUserLeaveRoom(eventData)
3216 * {
3217 *     document.getElementById("txtLog").innerHTML="用户"+eventData.uid+"离开了房间"+eventData.rid;
3218 * }
3219 */
3220 IYYTempAudioSession.USER_LEAVE_ROOM = "YY_TEMP_AUDIO_SESSION_USER_LEAVE";
3221 
3222 /**
3223 * 说话人数变化事件。当临时语音房间的说话人数发生变化时触发,即当有人调用startSpeak或stopSpeak成功时会触发。
3224 * @field
3225 * @example
3226 * 侦听函数格式: function(eventData){    } 
3227 * eventData.speakerList: Array类型  当前房间可以说话的人的uid。
3228 * @example
3229 * 使用示例:
3230 * yy.tempAudioSession.addEventListener(IYYTempAudioSession.SPEAKER_CHANGED,onSpeakerChanged);
3231 *
3232 * function onSpeakerChanged(eventData)
3233 * {
3234 *     document.getElementById("txtSpeakerEventLog").innerHTML += "说话人数变化:["+eventData.speakerList.toString()+"]<br/>";
3235 * }
3236 */
3237 IYYTempAudioSession.SPEAKER_CHANGED = "YY_TEMP_AUDIO_SESSION_SPEAKER_CHANGED";
3238 
3239 
3240 
3241 
3242 
3243 
3244 //--------------------------------------IYYUser----------------------------------
3245 /**
3246 * IYYUser 构造函数。
3247 * @extends IYYCommon
3248 * @class 用户信息接口。提供获取用户的信息,接收用户信息变化事件等功能。
3249 */
3250 function IYYUser() {
3251 
3252 };
3253 
3254 
3255 IYYUser.prototype = new IYYCommon();
3256 
3257 /**
3258 * 获取当前用户的信息。
3259 * @returns 返回当前用户信息,是一个Object对象。具体属性如下。<br/>
3260 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3261 * <b>uid</b>: Number类型 用户的uid,唯一标识id。<br/>
3262 * <b>imId</b>: Number类型 用户的YY号。<br/>
3263 * <b>level</b>: String类型 用户的等级。<br/>
3264 * <b>name</b>: Number类型 用户的名称。<br/>
3265 * <b>role</b>: Number类型 用户的马甲 对应的信息如下:<br/>
3266 * 无效角色 0 <br/>
3267 * 未知用户 灰马 20 <br/>
3268 * 游客(U) 白马 25 <br/>
3269 * 临时嘉宾(G) 浅绿色马甲 66 <br/>
3270 * 嘉宾(VIP) 绿马 88 <br/>
3271 * 会员(R) 蓝马 100 <br/>
3272 * 二级子频道管理员(CA2) 粉马 150 <br/>
3273 * 子频道管理员(CA) 红马 175 <br/>
3274 * 全频道管理员(MA) 黄马 200 <br/>
3275 * 频道总管理(VP) 橙马 230 <br/>
3276 * 频道所有者(OW) 紫马 255 <br/>
3277 * 客服 300 <br/>
3278 * 歪歪官方人员 黑马 1000 。<br/>
3279 * <b>sex</b>: Number类型 用户的性别  0=女 1=男 。<br/>
3280 * <b>sign</b>: String类型 用户的签名。<br/>
3281 * <b>vip</b>: Boolean类型 是否是会员trur=会员,false=非会员。<br/>
3282 * <b>vipLevel</b>: Number类型 游会员的等级。<br/>
3283 * <b>points</b>: Number类型 用户的个人积分。<br/>
3284 * <b>contribution</b>: Number类型 用户对当前频道的贡献值。<br/>
3285 
3286 * @type Object
3287 * @example
3288 * 使用示例:
3289 * var userInfo = yy.user.getCurrentUserInfo();
3290 * 成功的返回值示例:{ ret:0,uid:249267551,name:"美羊羊",vip:false,points:4125,imId:293451745,sex:0,sign:"很困了想睡觉",level:128,role:25,vipLevel:0,contribution:0}
3291 * 失败的返回值示例:{ ret:984832}
3292 
3293 */
3294 IYYUser.prototype.getCurrentUserInfo = function() {
3295     var result = callExternal("IUser_GetCurrnetUserInfo");
3296     if (result.ret === 0) {
3297         return parseUserInfo(result);
3298     }
3299     else {
3300         return result;
3301     }
3302 };
3303 
3304 
3305 /**
3306 * 获取指定的用户的信息。指定的用户必须在当前大频道中。
3307 * @returns 返回指定用户信息,是一个Object对象。返回信息的格式同getCurrentUserInfo接口一致。
3308 * @param {Number} uid 用户的唯一标识id,即uid,<b>不是YY号</b> 。
3309 * @type Object
3310 * @see #getCurrentUserInfo
3311 */
3312 IYYUser.prototype.getUserInfo = function(uid) {
3313     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
3314     if (typeof uid !== "number" || isNaN(uid)) return { ret: yy_e_api_param_error };
3315     var result = callExternal("IUser_GetUserInfo", uid);
3316     if (result.ret === 0) {
3317         return parseUserInfo(result);
3318     }
3319     else {
3320         return result;
3321     }
3322 };
3323 
3324 /**
3325 * 修改用户昵称。调用此接口修改自己的昵称。两次调用必须间隔1秒以上。
3326 * @param {String} newName 用户的新昵称,用户昵称需要符合相关要求。
3327 * @returns 返回调用是否成功,具体属性如下。<br/>
3328 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3329 * @type Object
3330 */
3331 IYYUser.prototype.rename = function(newName) {
3332     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
3333     if (typeof newName !== "string") return { ret: yy_e_api_param_error };
3334     var result = callExternal("IUserEx_Rename", newName);
3335     return result;
3336 };
3337 
3338 
3339 /**
3340 * 当前用户信息变更事件。当前用户昵称,性别,签名,马甲修改的时候会触发此事件。
3341 * @field
3342 * @example
3343 * 侦听函数格式: function(eventData){    } 
3344 * eventData: Object类型 变化后的用户信息。
3345 * @example
3346 * 使用示例:
3347 * yy.user.addEventListener(IYYUser.USER_INFO_CHANGED,onChange);
3348 *
3349 * function onChange(eventData)
3350 * {
3351 *    document.getElementById("txtLog").innerHTML=eventData.name+ "的信息发生了变化";
3352 * }
3353 * @see #getCurrentChannelInfo
3354 */
3355 IYYUser.USER_INFO_CHANGED = "YY_USER_INFO_CHANGED";
3356 
3357 
3358 //-----------------------------------------------IYYVideo-----------------------------
3359 
3360 /**
3361 * IYYVideo 构造函数。
3362 * @extends IYYCommon
3363 * @class 提供视频直播相关功能,所有方法需要调用lock后才能使用。应用需要认证才能使用视频功能,具体请联系YY开放平台。
3364 */
3365 function IYYVideo() {
3366 
3367 };
3368 
3369 IYYVideo.prototype = new IYYCommon();
3370 
3371 /**
3372 * 获取当前计算机摄像头名称列表。
3373 * @returns 返回摄像头列表,具体属性如下。<br/>
3374 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3375 * <b>cameras</b>: Array类型 摄像头名称列表。<br/>
3376 * @type Object
3377 * @example 
3378 * 使用示例:
3379 * var result = yy.video.getCameraList();
3380 * if(result.ret==0)
3381 * {
3382 *     document.getElementById("txtLog").innerHTML = "本机摄像头为:" + result.cameras;
3383 * }
3384 *   
3385 * 成功的返回值示例:{ ret:0,cameras:["camera1","camera2"]}
3386 * 失败的返回值示例:{ ret:984832}
3387 */
3388 IYYVideo.prototype.getCameraList = function () {
3389 
3390     var result = callExternal("IVideo_GetCameraList");
3391     if (result.ret == 0) {
3392         return { ret: 0, cameras: result.cameras.concat() }
3393     }
3394     else {
3395         return result;
3396     }
3397 
3398 };
3399 
3400 /**
3401 * 开始视频直播。缺省的分辨率360x240
3402 * @param {Number} cameraIndex 视频摄像头的索引。索引必须是有效的非负整数,如果计算机上有多个摄像头,索引分别为0,1,2...以此类推。
3403 * @returns 返回调用是否成功,具体属性如下。<br/>
3404 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3405 * @type Object
3406 * @see #setVideoWindow_640x480 #setVideoWindow_480x360
3407 */
3408 IYYVideo.prototype.startPublish = function (cameraIndex) {
3409     if (arguments.length !== 1) return { ret: yy_e_api_param_error };
3410     if (typeof cameraIndex !== "number" || isNaN(cameraIndex)) return { ret: yy_e_api_param_error };
3411     var result = callExternal("IVideo_StartPublish", cameraIndex);
3412     return result;
3413 };
3414 
3415 /**
3416 * 结束视频直播。
3417 * @returns 返回调用是否成功,具体属性如下。<br/>
3418 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3419 * @type Object
3420 */
3421 IYYVideo.prototype.stopPublish = function () {
3422     var result = callExternal("IVideo_StopPublish");
3423     return result;
3424 };
3425 
3426 
3427 /**
3428 * 调整视频窗口的大小和位置。
3429 * @param {Number} x 指定窗口位置的x值</b> 。
3430 * @param {Number} y 指定窗口位置的y值</b> 。
3431 * @param {Number} width 指定窗口的宽度 。
3432 * @param {Number} height 指定窗口的高度 。
3433 * @returns 返回调用是否成功,具体属性如下。<br/>
3434 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3435 * @type Object
3436 */
3437 IYYVideo.prototype.setVideoWindowPosition = function (x, y, width, height) {
3438     if (arguments.length !== 4) return { ret: yy_e_api_param_error };
3439     if (typeof x !== "number" || typeof y !== "number" || typeof width !== "number" || typeof height !== "number") return { ret: yy_e_api_param_error };
3440     var result = callExternal("IVideo_SetVideoWindowPosition", x, y, width, height);
3441     return result;
3442 };
3443 
3444 /**
3445 * 调整主播直播视频窗口的大小和位置。
3446 * @param {Number} x 指定窗口位置的x值</b> 。
3447 * @param {Number} y 指定窗口位置的y值</b> 。
3448 * @param {Number} width 指定窗口的宽度 。
3449 * @param {Number} height 指定窗口的高度 。
3450 * @returns 返回调用是否成功,具体属性如下。<br/>
3451 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3452 * @type Object
3453 */
3454 IYYVideo.prototype.setPublishVideoWindowPosition = function (x, y, width, height) {
3455     if (arguments.length !== 4) return { ret: yy_e_api_param_error };
3456     if (typeof x !== "number" || typeof y !== "number" || typeof width !== "number" || typeof height !== "number") return { ret: yy_e_api_param_error };
3457     var result = callExternal("IVideo_SetPublishVideoWindowPosition", x, y, width, height);
3458     return result;
3459 };
3460 
3461 /**
3462 * 调整指定主播的视频订阅窗口的大小和位置。订阅多个视频的时候,可以对指定主播的视频窗口进行单独调整。
3463 * @param {Number} x 指定窗口位置的x值</b> 。
3464 * @param {Number} y 指定窗口位置的y值</b> 。
3465 * @param {Number} width 指定窗口的宽度 。
3466 * @param {Number} height 指定窗口的高度 。
3467 * @param {Number} uid 指定主播的uid 。
3468 * @returns 返回调用是否成功,具体属性如下。<br/>
3469 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3470 * @type Object
3471 */
3472 IYYVideo.prototype.setSubscribeVideoWindowPosition = function (x, y, width, height, uid) {
3473     if (arguments.length !== 5) return { ret: yy_e_api_param_error };
3474     if (typeof x !== "number" || typeof y !== "number" || typeof width !== "number" || typeof height !== "number" || typeof uid !== "number") return { ret: yy_e_api_param_error };
3475     var result = callExternal("IVideo_SetSubscribeVideoWindowPosition", x, y, width, height, uid);
3476     return result;
3477 };
3478 
3479 /**
3480 * 锁定视频直播。锁定后才能调用视频直播的其他API,同时当前YY的其他应用无法调用视频直播。
3481 * @returns 返回调用是否成功,具体属性如下。<br/>
3482 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3483 * @type Object
3484 */
3485 IYYVideo.prototype.lock = function () {
3486     var result = callExternal("IVideo_Lock");
3487     return result;
3488 }
3489 
3490 /**
3491 * 解锁视频直播,使其他应用可以使用摄像头视频。所有参数(例如直播分辨率)变为缺省值。
3492 * @returns 返回调用是否成功,具体属性如下。<br/>
3493 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3494 * @type Object
3495 */
3496 IYYVideo.prototype.unlock = function () {
3497     var result = callExternal("IVideo_Unlock");
3498     return result;
3499 }
3500 
3501 /**
3502 * 获取当前子频道的正在直播的主播列表。
3503 * @returns 返回主播uid列表,具体属性如下。<br/>
3504 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3505 * <b>publishList</b>: Array类型 主播uid列表。<br/>
3506 * @type Object
3507 * @example 
3508 * 使用示例:
3509 * var result = yy.video.getPublishUsers();
3510 * if(result.ret==0)
3511 * {
3512 *     document.getElementById("txtLog").innerHTML = "正在直播的主播有:" + result.publishList;
3513 * }
3514 *   
3515 * 成功的返回值示例:{ ret:0,publishList:[909011223,909085545]}
3516 * 失败的返回值示例:{ ret:984832}
3517 */
3518 IYYVideo.prototype.getPublishUsers = function () {
3519     var result = callExternal("IVideo_GetPublishUsers");
3520     if (result.ret == 0) {
3521         return { ret: 0, publishList: result.user_list.concat() };
3522     }
3523     else {
3524         return result;
3525     }
3526 }
3527 /**
3528 * 开始视频订阅,即收看指定主播的直播。如果已经订阅了一个直播,需要先停止后才能订阅新的直播。
3529 * @param {Number} uid 主播的uid,主播即开播视频直播的人,getPublishUsers以获取当前正在直播的主播。
3530 * @returns 返回调用是否成功,具体属性如下。<br/>
3531 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3532 * @type Object
3533 * @see #stopSubscribeVideo #getPublishUsers
3534 */
3535 IYYVideo.prototype.startSubscribeVideo = function (uid) {
3536     var result = callExternal("IVideo_StartSubscribeVideo",uid);
3537     return result;
3538 }
3539 
3540 /**
3541 * 停止视频订阅,即关闭正在收看的视频。有效的主播uid才能停止订阅。
3542 * @param {Number} uid 要停止订阅的主播的uid,主播即开播视频直播的人,getPublishUsers以获取当前正在直播的主播。
3543 * @returns 返回调用是否成功,具体属性如下。<br/>
3544 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3545 * @type Object
3546 * @see #startSubscribeVideo #getPublishUsers
3547 */
3548 IYYVideo.prototype.stopSubscribeVideo = function (uid) {
3549     var result = callExternal("IVideo_StopSubscribeVideo", uid);
3550     return result;
3551 }
3552 
3553 /**
3554 * 设置发起直播时的视频属性。启用重新开始直播才生效。
3555 * @param {Number} key 视频属性Id。
3556 * @param {Number} value 属性值。
3557 * @returns 返回调用是否成功,具体属性如下。<br/>
3558 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3559 * @type Object
3560 */
3561 IYYVideo.prototype.setProperty = function (key, value) {
3562     if (arguments.length !== 2) return { ret: yy_e_api_param_error };
3563     if (typeof key !== "number" || typeof value !== "number") return { ret: yy_e_api_param_error };
3564     var result = callExternal("IVideo_SetProperty", key, value);
3565     return result;
3566 }
3567 
3568 /**
3569 * 设置直播的视频分辨率为640x480,需要重新开始直播才生效。
3570 * @returns 返回调用是否成功,具体属性如下。<br/>
3571 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3572 * @type Object
3573 */
3574 IYYVideo.prototype.setPublishVideo_640x480 = function () {
3575     var result;
3576     var errRes = 0;
3577     result = yy.video.setProperty(IYYVideo.ConfigAttr.CUR_BITRATE_LD_PID, 500 * 1000);
3578     if (result.ret != 0) errRes = result.ret;
3579     result = yy.video.setProperty(IYYVideo.ConfigAttr.MIN_BITRATE_LD_PID, 333 * 1000);
3580     if (result.ret != 0) errRes = result.ret;
3581     result = yy.video.setProperty(IYYVideo.ConfigAttr.MAX_BITRATE_LD_PID, 666 * 1000);
3582     if (result.ret != 0) errRes = result.ret;
3583     result = yy.video.setProperty(IYYVideo.ConfigAttr.RESOLUTION_PID, IYYVideo.RatioAttr.RATIO_TRY_640x480);
3584     if (result.ret != 0) errRes = result.ret;
3585     result = yy.video.setProperty(IYYVideo.ConfigAttr.ENC_PICTURE_RATIO_PID, IYYVideo.PictureRatioAttr.RESOLUTION_RATIO_4x3);
3586     if (result.ret != 0) errRes = result.ret;
3587     result = yy.video.setProperty(IYYVideo.ConfigAttr.TRY_USING_2_THREAD_PID, 1);
3588     if (result.ret != 0) errRes = result.ret;
3589     result = yy.video.setProperty(IYYVideo.ConfigAttr.QUALITY_DELAY_MODE_PID, IYYVideo.QualityDelayMode.HIGHT_QUALITY_MODE);
3590     if (result.ret != 0) errRes = result.ret;
3591     return { ret: errRes };
3592     
3593 }
3594 
3595 /**
3596 * 设置直播的视频分辨率为480x360,需要重新开始直播才生效。
3597 * @returns 返回调用是否成功,具体属性如下。<br/>
3598 * <b>ret</b>: Number类型 返回码 0=成功,非0值失败,具体请参考错误代码。<br/>
3599 * @type Object
3600 */
3601 IYYVideo.prototype.setPublishVideo_480x360 = function () {
3602     var result;
3603     var errRes = 0;
3604     result = yy.video.setProperty(IYYVideo.ConfigAttr.CUR_BITRATE_LD_PID, 300 * 1000);
3605     if (result.ret != 0) errRes = result.ret;
3606     result = yy.video.setProperty(IYYVideo.ConfigAttr.MIN_BITRATE_LD_PID, 200 * 1000);
3607     if (result.ret != 0) errRes = result.ret;
3608     result = yy.video.setProperty(IYYVideo.ConfigAttr.MAX_BITRATE_LD_PID, 400 * 1000);
3609     if (result.ret != 0) errRes = result.ret;
3610     result = yy.video.setProperty(IYYVideo.ConfigAttr.RESOLUTION_PID, IYYVideo.RatioAttr.RATIO_TRY_480x360);
3611     if (result.ret != 0) errRes = result.ret;
3612     result = yy.video.setProperty(IYYVideo.ConfigAttr.ENC_PICTURE_RATIO_PID, IYYVideo.PictureRatioAttr.RESOLUTION_RATIO_4x3);
3613     if (result.ret != 0) errRes = result.ret;
3614     result = yy.video.setProperty(IYYVideo.ConfigAttr.TRY_USING_2_THREAD_PID, 1);
3615     if (result.ret != 0) errRes = result.ret;
3616     result = yy.video.setProperty(IYYVideo.ConfigAttr.QUALITY_DELAY_MODE_PID, IYYVideo.QualityDelayMode.HIGHT_QUALITY_MODE);
3617     if (result.ret != 0) errRes = result.ret;
3618     return { ret: errRes };
3619 }
3620 
3621 /**
3622 * 主播直播结果事件。主播开始直播后,根据此事件判断直播是否是成功的。
3623 * @field
3624 * @example
3625 * 侦听函数格式: function(eventData){    } 
3626 * eventData.status: Number类型 直播结果 0=成功开始直播,1=直播失败
3627 * @example
3628 * 使用示例:
3629 * yy.video.addEventListener(IYYVideo.PUBLISH_STATUS,onPublishChange);
3630 *
3631 * function onPublishChange(eventData)
3632 * {
3633 *    document.getElementById("txtLog").innerHTML=eventData.status==0?"成功开始直播":"直播未成功";
3634 * }
3635 */
3636 IYYVideo.PUBLISH_STATUS = "YY_VIDEO_PUBLISH_STATUS";
3637 
3638 
3639 /**
3640 * 摄像头状态变化事件。通知主播摄像头状态发生变化。
3641 * @field
3642 * @example
3643 * 侦听函数格式: function(eventData){    } 
3644 * eventData.status: Number类型 摄像头状态 0=摄像头就绪,1=摄像头就绪暂不可用(被别的程序占用),2=摄像头无法支持
3645 * @example
3646 * 使用示例:
3647 * yy.video.addEventListener(IYYVideo.CAMERA_STATUS,onCameraChange);
3648 *
3649 * function onCameraChange(eventData)
3650 * {
3651 *    document.getElementById("txtLog").innerHTML=(eventData.status==0)?"摄像头正常":"摄像头失效";
3652 * }
3653 */
3654 IYYVideo.CAMERA_STATUS = "YY_VIDEO_CAMERA_STATUS";
3655 
3656 /**
3657 * 主播直播状态变化事件。当当前子频道有主播直播状态发生变化会触发,即主播开始直播或者结束直播的时候都会通知子频道中侦听此事件的用户。
3658 * @field
3659 * @example
3660 * 侦听函数格式: function(eventData){    } 
3661 * eventData.uid: Number类型 直播状态发生变化的主播的uid。
3662 * eventData.status: Number类型 主播状态 0=主播开始直播,1=主播结束直播
3663 * @example
3664 * 使用示例:
3665 * yy.video.addEventListener(IYYVideo.SUBSCRIBE_STATUS,onSubscribeChange);
3666 *
3667 * function onSubscribeChange(eventData)
3668 * {
3669 *    document.getElementById("txtLog").innerHTML="主播"+eventData.uid+(eventData.status==0?"开始直播了":"停止直播了");
3670 * }
3671 */
3672 IYYVideo.SUBSCRIBE_STATUS = "YY_VIDEO_SUBSCRIBE_STATUS";
3673 
3674 /**
3675 * 视频编码属性。
3676 * @field
3677 * @example
3678 * IYYVideo.ConfigAttr.RESOLUTION_PID 4 分辨率
3679 * IYYVideo.ConfigAttr.TRY_USING_2_THREAD_PID 5 是否开启双线程,值为布尔值
3680 * IYYVideo.ConfigAttr.CUR_BITRATE_LD_PID 7 当前码率 
3681 * IYYVideo.ConfigAttr.MIN_BITRATE_LD_PID 8 码率最小值
3682 * IYYVideo.ConfigAttr.MAX_BITRATE_LD_PID 9 码率最大值
3683 * IYYVideo.ConfigAttr.ENC_PICTURE_RATIO_PID 17 编码画面比例
3684 * IYYVideo.ConfigAttr.QUALITY_DELAY_MODE_PID 18 画质/延时模式选择
3685 */
3686 IYYVideo.ConfigAttr =
3687 {
3688     //!分辨率
3689     RESOLUTION_PID: 4,
3690     //!是否开启双线程,值为布尔值
3691     TRY_USING_2_THREAD_PID: 5,
3692     //!当前码率 
3693     CUR_BITRATE_LD_PID: 7,
3694     //!码率最小值
3695     MIN_BITRATE_LD_PID: 8,
3696     //!码率最大值
3697     MAX_BITRATE_LD_PID: 9,
3698     //!编码画面比例
3699     ENC_PICTURE_RATIO_PID: 17,
3700     //!画质/延时模式选择
3701     QUALITY_DELAY_MODE_PID: 18
3702 }
3703 
3704 /**
3705 * 视频分辨率常量值。
3706 * @field
3707 * @example
3708 * IYYVideo.RatioAtrr.RATIO_TRY_640x480 0 640x480分辨率
3709 * IYYVideo.RatioAttr.RATIO_TRY_480x360 6 480x360分辨率
3710 */
3711 IYYVideo.RatioAttr =
3712 {
3713     //!640x480分辨率
3714     RATIO_TRY_640x480: 0,
3715     //!480x360分辨率
3716     RATIO_TRY_480x360: 6
3717 }
3718 
3719 /**
3720 * 画面比例常量值。
3721 * @field
3722 * @example
3723 * IYYVideo.PictureRatioAttr.RESOLUTION_RATIO_4x3 1 按4:3比例
3724 */
3725 IYYVideo.PictureRatioAttr =
3726 {
3727     //!按4:3比例
3728     RESOLUTION_RATIO_4x3: 1,
3729 }
3730 
3731 /**
3732 * 画质/延时模式常量值。
3733 * @field
3734 * @example
3735 * IYYVideo.QualityDelayMode.HIGHT_QUALITY_MODE 1 高质模式
3736 */
3737 IYYVideo.QualityDelayMode =
3738 {
3739     //!高质模式
3740     HIGHT_QUALITY_MODE: 1,
3741 }
3742 
3743 /**
3744 * 调用YY平台提供的接口
3745 * @private
3746 */
3747 function callExternal() {
3748 
3749     try {
3750         if (debugMode) {//打印出日志
3751             var strArgu = "(";
3752             var sp = "";
3753             for (var i = 1; i < arguments.length; i++) {
3754                 switch (typeof arguments[i]) {
3755                     case "string":
3756                         strArgu += sp + "'" + arguments[i] + "'";
3757                         break;
3758                     case "number":
3759                         strArgu += sp + arguments[i];
3760                         break;
3761                     case "boolean":
3762                         strArgu += sp + arguments[i];
3763                         break;
3764                     case "object":
3765                         if (arguments[i] instanceof Array) {
3766                             strArgu += sp + "'[" + arguments[i].toString() + "]'";
3767                         }
3768                         else
3769                             strArgu += sp + arguments[i].toString();
3770                         break;    
3771                     default:
3772                         strArgu += sp + arguments[i].toString();
3773                 }
3774 
3775                 sp = ","
3776             }
3777             strArgu += ");"
3778             var runCode = "window.external." + arguments[0] + strArgu;
3779             yytrace(runCode);        
3780         }
3781         
3782         var ret = "{ \"ret\": 62003 }";//如果api不存在,返回错误代码
3783         var yyexternal = window.external;
3784         switch (arguments[0]) {
3785 
3786             case "IYY_GetVersion":
3787                 ret = yyexternal.IYY_GetVersion();
3788                 break;
3789             case "IYYEx_GetYYVersion":
3790                 ret = yyexternal.IYYEx_GetYYVersion();
3791                 break;
3792             case "IYYEx_GetWebAppShowMode":
3793                 ret = yyexternal.IYYEx_GetWebAppShowMode();
3794                 break;
3795             case "IAudio_StartRecord":
3796                 if (arguments.length === 1) {
3797                     ret = yyexternal.IAudio_StartRecord("");
3798                 }
3799                 else {
3800                     ret = yyexternal.IAudio_StartRecord(arguments[1]);
3801                 }
3802                 break;
3803             case "IAudio_StopRecord":
3804                 ret = yyexternal.IAudio_StopRecord();
3805                 break;
3806             case "IAudio_OpenKaraoke":
3807                 ret = yyexternal.IAudio_OpenKaraoke();
3808                 break;
3809             case "IAudio_CloseKaraoke":
3810                 ret = yyexternal.IAudio_CloseKaraoke();
3811                 break;
3812             case "IAudio_EnableAudioMixing":
3813                 ret = yyexternal.IAudio_EnableAudioMixing();
3814                 break;
3815             case "IAudio_DisableAudioMixing":
3816                 ret = yyexternal.IAudio_DisableAudioMixing();
3817                 break;
3818             case "IAudio_SetKaraokePlayerPath":
3819                 ret = yyexternal.IAudio_SetKaraokePlayerPath(arguments[1]);
3820                 break;
3821             case "IAudio_ResetKaraokePlayerPath":
3822                 ret = yyexternal.IAudio_ResetKaraokePlayerPath(arguments[1],arguments[2]);
3823                 break;
3824             case "IChannel_GetCurrentChannelInfo":
3825                 ret = yyexternal.IChannel_GetCurrentChannelInfo();
3826                 break;
3827             case "IChannel_GetCurrentSubChannelInfo":
3828                 ret = yyexternal.IChannel_GetCurrentSubChannelInfo();
3829                 break;
3830             case "IChannel_GetChannelInfo":
3831                 ret = yyexternal.IChannel_GetChannelInfo(arguments[1]);
3832 
3833                 break;
3834             case "IChannel_GetRootChannelId":
3835                 ret = yyexternal.IChannel_GetRootChannelId();
3836                 break;
3837             case "IChannel_GetSubChannelIds":
3838                 ret = yyexternal.IChannel_GetSubChannelIds(arguments[1]);
3839                 break;
3840             case "IChannelUserList_GetUserList":
3841                 ret = yyexternal.IChannelUserList_GetUserList(arguments[1]);
3842                 break;
3843             case "IChannel_GetChannelStyle":
3844                 ret = yyexternal.IChannel_GetChannelStyle();
3845                 break;
3846             case "IChannelAppMsg_SendMsgToSubChannel":
3847                 ret = yyexternal.IChannelAppMsg_SendMsgToSubChannel(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
3848                 break;
3849             case "IChannelAppMsg_SendMsgToUsers":
3850 
3851                 ret = yyexternal.IChannelAppMsg_SendMsgToUsers("[" + arguments[1].toString() + "]", arguments[2], arguments[3], arguments[4], arguments[5]);
3852                 break;
3853             case "IChannelAppMsg_SendMsgToSubChannelEx":
3854                 ret = yyexternal.IChannelAppMsg_SendMsgToSubChannelEx(arguments[1], arguments[2], arguments[3], arguments[4]);
3855                 break;
3856             case "IChannelAppMsg_SendMsgToUsersEx":
3857                 ret = yyexternal.IChannelAppMsg_SendMsgToUsersEx("[" + arguments[1].toString() + "]", arguments[2], arguments[3], arguments[4]);
3858                 break;
3859             case "IChannelMicList_GetMicList":
3860                 ret = yyexternal.IChannelMicList_GetMicList();
3861                 break;
3862             case "IChannelMicList_JoinMicList":
3863                 ret = yyexternal.IChannelMicList_JoinMicList();
3864                 break;
3865             case "IChannelMicList_LeaveMicList":
3866                 ret = yyexternal.IChannelMicList_LeaveMicList();
3867                 break;
3868             case "IChannelMicList_PullUserToMicList":
3869                 ret = yyexternal.IChannelMicList_PullUserToMicList(arguments[1]);
3870                 break;
3871             case "IChannelMicList_KickMicListUser":
3872                 ret = yyexternal.IChannelMicList_KickMicListUser(arguments[1]);
3873                 break;
3874             case "IChannelMicList_MoveUserToTop":
3875                 ret = yyexternal.IChannelMicList_MoveUserToTop(arguments[1]);
3876                 break;
3877             case "IChannelMicList_ClearMicList":
3878                 ret = yyexternal.IChannelMicList_ClearMicList();
3879                 break;
3880             case "IChannelMicList_GetLinkedMicList":
3881                 ret = yyexternal.IChannelMicList_GetLinkedMicList();
3882                 break;
3883             case "IChannelMicList_LinkMicToTheQueueHead":
3884                 ret = yyexternal.IChannelMicList_LinkMicToTheQueueHead(arguments[1]);
3885                 break;
3886             case "IChannelMicList_RemoveFromLinkedMicList":
3887                 ret = yyexternal.IChannelMicList_RemoveFromLinkedMicList(arguments[1]);
3888                 break;
3889             case "IChannelMicList_GetMicListMode":
3890                 ret = yyexternal.IChannelMicList_GetMicListMode();
3891                 break;
3892             case "IChannelMicList_SetMicListMode":
3893                 ret = yyexternal.IChannelMicList_SetMicListMode(arguments[1]);
3894                 break;  
3895 
3896             case "IChannelMicList_MoveUpOnePosition":
3897                 ret = yyexternal.IChannelMicList_MoveUpOnePosition(arguments[1]);
3898                 break;
3899             case "IChannelMicList_MoveDownOnePosition":
3900                 ret = yyexternal.IChannelMicList_MoveDownOnePosition(arguments[1]);
3901                 break;  
3902             case "IChannelMicList_GetFirstMicSeconds":
3903                 ret = yyexternal.IChannelMicList_GetFirstMicSeconds();
3904                 break;
3905             case "IChannelMicList_DoubleFirstMicSeconds":
3906                 ret = yyexternal.IChannelMicList_DoubleFirstMicSeconds();
3907                 break;  
3908             case "IChannelMicList_EnableJoinMicList":
3909                 ret = yyexternal.IChannelMicList_EnableJoinMicList();
3910                 break;
3911             case "IChannelMicList_DisableJoinMicList":
3912                 ret = yyexternal.IChannelMicList_DisableJoinMicList();
3913                 break;  
3914             case "IChannelMicList_ControlMic":
3915                 ret = yyexternal.IChannelMicList_ControlMic();
3916                 break;
3917             case "IChannelMicList_ReleaseMic":
3918                 ret = yyexternal.IChannelMicList_ReleaseMic();
3919                 break;                                                  
3920             case "IChannelMicList_IsJoinMicListEnabled":
3921                 ret = yyexternal.IChannelMicList_IsJoinMicListEnabled();
3922                 break;                  
3923             case "IChannelMicList_IsMicListControlled":
3924                 ret = yyexternal.IChannelMicList_IsMicListControlled();
3925                 break;                  
3926             case "IChannelMicList_SendMicListNotification":
3927                 ret = yyexternal.IChannelMicList_SendMicListNotification();
3928                 break;  
3929                                 
3930             case "IChannelUserController_EnableMsg":
3931                 ret = yyexternal.IChannelUserController_EnableMsg(arguments[1]);
3932                 break;
3933             case "IChannelUserController_DisableMsg":
3934                 ret = yyexternal.IChannelUserController_DisableMsg(arguments[1]);
3935                 break;
3936             case "IChannelUserController_EnableSpeak":
3937                 ret = yyexternal.IChannelUserController_EnableSpeak(arguments[1]);
3938                 break;
3939             case "IChannelUserController_DisableSpeak":
3940                 ret = yyexternal.IChannelUserController_DisableSpeak(arguments[1]);
3941                 break;
3942             case "IChannelUserController_IsMsgEnabled":
3943                 ret = yyexternal.IChannelUserController_IsMsgEnabled(arguments[1]);
3944                 break;
3945             case "IChannelUserController_IsSpeakEnabled":
3946                 ret = yyexternal.IChannelUserController_IsSpeakEnabled(arguments[1]);
3947                 break;
3948             case "IChannelUserController_JumpToSubChannel":
3949                 ret = yyexternal.IChannelUserController_JumpToSubChannel(arguments[1]);
3950                 break;
3951             case "IChannelUserController_PullToSubChannel":
3952                 ret = yyexternal.IChannelUserController_PullToSubChannel(arguments[1], arguments[2]);
3953                 break;
3954             case "IChannelUserController_GetUserSubChannelId":
3955                 ret = yyexternal.IChannelUserController_GetUserSubChannelId(arguments[1]);
3956                 break;
3957             case "IChannelUserController_SetUserRole":
3958                 ret = yyexternal.IChannelUserController_SetUserRole(arguments[1], arguments[2], arguments[3]);
3959                 break;
3960             case "IReceptionChannel_SetReceptionChannel":
3961                 ret = yyexternal.IReceptionChannel_SetReceptionChannel(arguments[1]);
3962                 break;
3963             case "IReceptionChannel_GetReceptionChannel":
3964                 ret = yyexternal.IReceptionChannel_GetReceptionChannel();
3965                 break;
3966             case "IReceptionChannel_UnSetReceptionChannel":
3967                 ret = yyexternal.IReceptionChannel_UnSetReceptionChannel();
3968                 break;
3969             case "IChannelUserListPopMenu_SetPopMenu":
3970                 ret = yyexternal.IChannelUserListPopMenu_SetPopMenu(arguments[1]);
3971                 break;
3972             case "IChannelUserListPopMenu_UnSetPopMenu":
3973                 ret = yyexternal.IChannelUserListPopMenu_UnSetPopMenu();
3974                 break;
3975             case "IChannelTabPage_SelectTabPage":
3976                 ret = yyexternal.IChannelTabPage_SelectTabPage();
3977                 break;
3978             case "ICloud_AddData":
3979                 ret = yyexternal.ICloud_AddData(arguments[1], arguments[2], arguments[3]);
3980                 break;
3981             case "ICloud_UpdateData":
3982                 ret = yyexternal.ICloud_UpdateData(arguments[1], arguments[2], arguments[3], "[" + arguments[4] + "]");
3983                 break;
3984             case "ICloud_DeleteData":
3985                 ret = yyexternal.ICloud_DeleteData("[" + arguments[1] + "]");
3986                 break;
3987             case "ICloud_QueryData":
3988                 ret = yyexternal.ICloud_QueryData("[" + arguments[1] + "]");
3989                 break;
3990             case "IFinance_Buy":
3991                 ret = yyexternal.IFinance_Buy(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);
3992                 break;
3993             case "IFinance_BuyByYuan":
3994                 ret = yyexternal.IFinance_BuyByYuan(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);
3995                 break;
3996             case "IFinance_BuyGifts":
3997                 ret = yyexternal.IFinance_BuyGifts(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8]);
3998                 break;
3999             case "IFinance_Recharge":
4000                 ret=yyexternal.IFinance_Recharge();
4001                 break;
4002             case "IIM_ChatTo":
4003                 ret = yyexternal.IIM_ChatTo(arguments[1], arguments[2]);
4004                 break;
4005             case "IIM_IsFriend":
4006                 ret = yyexternal.IIM_IsFriend(arguments[1]);
4007                 break;
4008             case "IIM_AddFriend":
4009                 ret = yyexternal.IIM_AddFriend(arguments[1]);
4010                 break;
4011             case "IIM_GetIMUserInfo":
4012                 ret = yyexternal.IIM_GetIMUserInfo(arguments[1]);
4013                 break;
4014             case "IIM_GetAllBuddyList":
4015                 ret = yyexternal.IIM_GetAllBuddyList();
4016                 break;
4017             case "IInteraction_GetInviter":
4018                 ret = yyexternal.IInteraction_GetInviter();
4019                 break;
4020             case "IInteraction_Invite":
4021                 ret = yyexternal.IInteraction_Invite(arguments[1]);
4022                 break;
4023             case "IInteraction_GetRunParams":
4024                 ret = yyexternal.IInteraction_GetRunParams();
4025                 break;
4026             case "IInteraction_CreateAppTicket":
4027                 ret = yyexternal.IInteraction_CreateAppTicket(arguments[1], arguments[2]);
4028                 break;
4029             case "IInteraction_Follow":
4030                 ret = yyexternal.IInteraction_Follow(arguments[1]);
4031                 break;
4032             case "IInteraction_UnFollow":
4033                 ret = yyexternal.IInteraction_UnFollow(arguments[1]);
4034                 break;
4035             case "IInteraction_GetFansCount":
4036                 ret = yyexternal.IInteraction_GetFansCount();
4037                 break;
4038             case "IInteraction_IsFans":
4039                 ret = yyexternal.IInteraction_IsFans(arguments[1]);
4040                 break;
4041             case "INet_BroadCastSubChannel":
4042                 ret = yyexternal.INet_BroadCastSubChannel(arguments[1], arguments[2]);
4043                 break;
4044             case "INet_BroadCastAllChannel":
4045                 ret = yyexternal.INet_BroadCastAllChannel(arguments[1]);
4046                 break;
4047             case "INet_BroadCastToUsers":
4048                 ret = yyexternal.INet_BroadCastToUsers(arguments[1], "[" + arguments[2].toString() + "]");
4049                 break;
4050             case "ISecurity_GetToken":
4051                 ret = yyexternal.ISecurity_GetToken();
4052                 break;
4053             case "ISecurity_ReportAbuse":
4054                 ret = yyexternal.ISecurity_ReportAbuse();
4055                 break;
4056             case "ISecurity_ReportScreenshot":
4057                 ret = yyexternal.ISecurity_ReportScreenshot();
4058                 break;
4059             case "ISecurity_KeywordFilter":
4060                 ret = yyexternal.ISecurity_KeywordFilter(arguments[1]);
4061                 break;
4062             case "ITempAudioSession_CreateRoom":
4063                 ret = yyexternal.ITempAudioSession_CreateRoom();
4064                 break;
4065             case "ITempAudioSession_EnterRoom":
4066                 ret = yyexternal.ITempAudioSession_EnterRoom(arguments[1]);
4067                 break;
4068             case "ITempAudioSession_LeaveRoom":
4069                 ret = yyexternal.ITempAudioSession_LeaveRoom();
4070                 break;
4071             case "ITempAudioSession_StartSpeak":
4072                 ret = yyexternal.ITempAudioSession_StartSpeak();
4073                 break;
4074             case "ITempAudioSession_StopSpeak":
4075                 ret = yyexternal.ITempAudioSession_StopSpeak();
4076                 break;
4077                 
4078             case "ITempAudioSession_SetVolume":
4079                 ret = yyexternal.ITempAudioSession_SetVolume(arguments[1]);
4080                 break;
4081             case "ITempAudioSession_GetVolume":
4082                 ret = yyexternal.ITempAudioSession_GetVolume();
4083                 break;    
4084             case "ITempAudioSession_GetOwner":
4085                 ret = yyexternal.ITempAudioSession_GetOwner();
4086                 break;   
4087                                             
4088             case "IUser_GetCurrnetUserInfo":
4089                 ret = yyexternal.IUser_GetCurrnetUserInfo();
4090                 break;
4091             case "IUser_GetUserInfo":
4092                 ret = yyexternal.IUser_GetUserInfo(arguments[1]);
4093                 break;
4094             case "IUserEx_Rename":
4095                 ret = yyexternal.IUserEx_Rename(arguments[1]);
4096                 break;
4097             case "IVideo_GetCameraList":
4098                 ret = yyexternal.IVideo_GetCameraList();
4099                 break;
4100             case "IVideo_StartPublish":
4101                 ret = yyexternal.IVideo_StartPublish(arguments[1]);
4102                 break;
4103             case "IVideo_StopPublish":
4104                 ret = yyexternal.IVideo_StopPublish();
4105                 break;
4106             case "IVideo_SetVideoWindowPosition":
4107                 ret = yyexternal.IVideo_SetVideoWindowPosition(arguments[1], arguments[2], arguments[3], arguments[4]);
4108                 break;
4109             case "IVideo_SetPublishVideoWindowPosition":
4110                 ret = yyexternal.IVideo_SetPublishVideoWindowPosition(arguments[1], arguments[2], arguments[3], arguments[4]);
4111                 break;
4112             case "IVideo_SetSubscribeVideoWindowPosition":
4113                 ret = yyexternal.IVideo_SetSubscribeVideoWindowPosition(arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
4114                 break;
4115             case "IVideo_Lock":
4116                 ret = yyexternal.IVideo_Lock();
4117                 break;
4118             case "IVideo_Unlock":
4119                 ret = yyexternal.IVideo_Unlock();
4120                 break;
4121             case "IVideo_GetPublishUsers":
4122                 ret = yyexternal.IVideo_GetPublishUsers();
4123                 break;
4124             case "IVideo_StartSubscribeVideo":
4125                 ret = yyexternal.IVideo_StartSubscribeVideo(arguments[1]);
4126                 break;
4127             case "IVideo_StopSubscribeVideo":
4128                 ret = yyexternal.IVideo_StopSubscribeVideo(arguments[1]);
4129                 break;
4130             case "IVideo_SetProperty":
4131                 ret = yyexternal.IVideo_SetProperty(arguments[1], arguments[2]);
4132                 break;
4133             case "SubscribeYYEvent":
4134                 ret = yyexternal.SubscribeYYEvent(arguments[1], arguments[2]);
4135                 break;
4136             case "SubscribeAudioEvent":
4137                 ret = yyexternal.SubscribeAudioEvent(arguments[1], arguments[2]);
4138                 break;
4139             case "SubscribeChannelEvent":
4140                 ret = yyexternal.SubscribeChannelEvent(arguments[1], arguments[2]);
4141                 break;
4142             case "SubscribeAppMsgEvent":
4143                 ret = yyexternal.SubscribeAppMsgEvent(arguments[1], arguments[2]);
4144                 break;
4145             case "SubscribeMicListEvent":
4146                 ret = yyexternal.SubscribeMicListEvent(arguments[1], arguments[2]);
4147                 break;
4148             case "SubscribePopMenuEvent":
4149                 ret = yyexternal.SubscribePopMenuEvent(arguments[1], arguments[2]);
4150                 break;
4151             case "SubscribeNetEvent":
4152                 ret = yyexternal.SubscribeNetEvent(arguments[1], arguments[2]);
4153                 break;
4154             case "SubscribeUserEvent":
4155                 ret = yyexternal.SubscribeUserEvent(arguments[1], arguments[2]);
4156                 break;
4157             case "SubscribeTempAudioSessionEvent":
4158                 ret = yyexternal.SubscribeTempAudioSessionEvent(arguments[1], arguments[2]);
4159                 break;
4160             case "SubscribeFinanceEvent":
4161                 ret = yyexternal.SubscribeFinanceEvent(arguments[1], arguments[2]);
4162                 break;
4163             case "SubscribeChannelChatEvent":
4164                 ret = yyexternal.SubscribeChannelChatEvent(arguments[1], arguments[2]);
4165                 break;
4166             case "SubscribeVideoEvent":
4167                 ret = yyexternal.SubscribeVideoEvent(arguments[1], arguments[2]);
4168                 break;
4169             default:
4170 
4171                 //ret = eval(runCode);
4172 
4173 
4174         }
4175         yytrace(ret); //打印返回值
4176         //返回值转json
4177         try {
4178             var retJson = eval("(" + ret + ")");
4179         } catch (exjson) {
4180             throw "返回值转json出错:"+exjson.message;
4181         }
4182 
4183 
4184         //如果无ret字段
4185         if (typeof (retJson.ret) !== "number") throw "NO_RET";
4186 
4187         //暂时停止统计
4188         //statisticApiCall(arguments[0], retJson);
4189 
4190         //escape中文,防止flashplayer bug
4191         switch (arguments[0]) {
4192 
4193             case "IChannel_GetChannelInfo":
4194             case "IChannel_GetCurrentSubChannelInfo":
4195             case "IChannel_GetCurrentChannelInfo":
4196                 retJson.name = escape(retJson.name);
4197                 break;
4198             case "IUser_GetCurrnetUserInfo":
4199             case "IUser_GetUserInfo":
4200                 retJson.name = escape(retJson.name);
4201                 retJson.sign = escape(retJson.sign);
4202                 break;
4203             case "IIM_GetIMUserInfo":
4204                 retJson.nick_name = escape(retJson.nick_name);
4205                 break;
4206             default:
4207         }
4208         
4209         return retJson;
4210 
4211         
4212 
4213     } catch (ex) {
4214         //E_NOINTERFACE api不存在 62003
4215         //E_INVALIDARG api调用参数错误62001
4216         //E_FAIL api调用失败  62000
4217         yytrace("错误! 原因[" + ex.name + "] "+ex.number+":" + ex.message);
4218         if (ex === "NO_RET") return { ret: yy_e_api_return_format_error, message: "返回信息没有ret属性" };
4219         else if (ex.number === -2146827858) return { ret: yy_e_api_not_exist, message: "api不存在! 原因:[" + ex.number + "]" + ex.message };
4220         else if (ex.number === -2146828283) return { ret: yy_e_api_param_error, message: "api调用参数错误! 原因:[" + ex.number + "]" + ex.message };
4221         else return { ret: yy_e_api_call_error, message: "api调用失败! 原因:[" + ex.number + "]" + ex.message };
4222     }
4223 
4224 
4225 }
4226 var yyTraceMaxLine = 256;
4227 var yyTraceData = [];
4228 var yyConsole = null;
4229 /**
4230 * 输出debug信息到控制台
4231 * @private
4232 */
4233 function yytrace(msg) {
4234 
4235     try {
4236         if (!debugMode) return;
4237         if (yyConsole == null) {
4238             yyConsole = document.getElementById("txtConsole");
4239         }
4240         if (yyConsole != null) {
4241             if (yyTraceData.length >= yyTraceMaxLine) {
4242                 yyTraceData.pop();
4243             }
4244             yyTraceData.unshift(msg);
4245             yyConsole.innerText = yyTraceData.join("\n");
4246         }
4247     } catch (exLog) {
4248         throw "打印日志错误!" + exLog + exLog.message;
4249     }
4250 }
4251 
4252 
4253 //创建api对象,供调用所有api,全局变量。
4254 window["yy"] = new IYY();
4255 
4256 //})(); //保存到命名空间中
4257 
4258 
4259 //---------------------------------------------------------数据类-----------------------------------------------------------------
4260 
4261 
4262 
4263 /**
4264 * 构造函数。
4265 * @class 简单存储条件过滤器,保存查询条件。
4266 */
4267 function YYCloudFilter() {
4268     /**
4269     * 对哪个字段进行过滤。
4270     * @field
4271     * @type Number
4272     */
4273     this.field = 0;
4274     /**
4275     * 操作符,比如大于小于等。
4276     * @field
4277     * @type Number
4278     */
4279     this.op = 0;
4280     /**
4281     * 字段数值。
4282     * @field
4283     * @type Object
4284     */
4285     this.value = null;
4286     /**
4287     * 和其他filter的关系。
4288     * @field
4289     * @type Number
4290     */
4291     this.condition = 0;
4292 }
4293 /**
4294 * 简单存储的字段表示常量。
4295 * @field
4296 * @example
4297 * YYCloudFilter.EField.NONE 0 无效字段
4298 * YYCloudFilter.EField.UNIQUE_KEY 1 唯一键 字段
4299 * YYCloudFilter.EField.USER_ID 2 uid字段
4300 * YYCloudFilter.EField.EXTERNAL_VALUE1 3 扩展int1 字段
4301 * YYCloudFilter.EField.EXTERNAL_VALUE2 4 扩展int2 字段
4302 * YYCloudFilter.EField.CREATE_TIME 5 创建时间
4303 * YYCloudFilter.EField.UPDATE_TIME 6 更新时间
4304 */
4305 YYCloudFilter.EField =
4306 {
4307     //!无效字段
4308     NONE: 0,
4309     //!key 唯一键 字段
4310     UNIQUE_KEY: 1,
4311     //!uid 字段
4312     USER_ID: 2,
4313     //!扩展int1 字段
4314     EXTERNAL_VALUE1: 3,
4315     //!扩展int2 字段
4316     EXTERNAL_VALUE2: 4,
4317     //!创建时间
4318     CREATE_TIME: 5,
4319     //!更新时间
4320     UPDATE_TIME: 6
4321 };
4322 
4323 /**
4324 * 简单存储的操作符常量。
4325 * @field
4326 * @example
4327 * YYCloudFilter.EFilterOperator.NONE 0 无效操作
4328 * YYCloudFilter.EFilterOperator.EQ 1 等于
4329 * YYCloudFilter.EFilterOperator.GE 2 大于等于
4330 * YYCloudFilter.EFilterOperator.LE 3 小于等于
4331 * YYCloudFilter.EFilterOperator.GREATER 4 大于
4332 * YYCloudFilter.EFilterOperator.LESS 5 小于
4333 */
4334 YYCloudFilter.EFilterOperator =
4335 {
4336     //! 无效操作
4337     NONE: 0,
4338     //! = 等于
4339     EQ: 1,
4340     //! >= 大于等于
4341     GE: 2,
4342     //! <= 小于等于	
4343     LE: 3,
4344     //! = 大于
4345     GREATER: 4,
4346     //! < 小于
4347     LESS: 5
4348 };
4349 
4350 /**
4351 * 简单存储的条件运算常量。
4352 * @field
4353 * @example
4354 * YYCloudFilter.EFilterCondition.NONE 0 无效条件
4355 * YYCloudFilter.EFilterCondition.AND  1 条件 与 and 
4356 * YYCloudFilter.EFilterCondition.OR 2 条件 或 or
4357 */
4358 YYCloudFilter.EFilterCondition =
4359 {
4360     //!无效条件
4361     NONE: 0,
4362     //! 条件 与 and 
4363     AND: 1,
4364     //! 条件 或 or
4365     OR: 2
4366 };
4367 
4368 /**
4369 * @private
4370 */
4371 YYCloudFilter.prototype.toString = function() {
4372     switch (this.field) {
4373         case YYCloudFilter.EField.EXTERNAL_VALUE1, YYCloudFilter.EField.EXTERNAL_VALUE2:
4374             return "{\"field\":" + this.field + ",\"op\":" + this.op + ",\"value\":" + this.value + ",\"condition\":" + this.condition + "}";
4375         case YYCloudFilter.EField.UNIQUE_KEY:
4376             return "{\"field\":" + this.field + ",\"op\":" + this.op + ",\"value\":\"" + this.value + "\",\"condition\":" + this.condition + "}";
4377         default:
4378             return "{\"field\":" + this.field + ",\"op\":" + this.op + ",\"value\":" + this.value + ",\"condition\":" + this.condition + "}";
4379     }
4380 
4381 
4382 };
4383 
4384 
4385 
4386 //---------------------------------------下面为回调函数------------------------------------------------------------------------------------------------
4387 //---------------------------------------下面为回调函数------------------------------------------------------------------------------------------------
4388 //---------------------------------------下面为回调函数------------------------------------------------------------------------------------------------
4389 
4390 
4391 /**
4392 * 运行时,应用图标被点击事件。
4393 * @private
4394 */
4395 function IYY_OnActive(activeCode) {
4396     if (debugMode) {
4397         yytrace(IYY.ACTIVE + ":" + activeCode);
4398     }
4399     yy.dispatchEvent(IYY.ACTIVE, { activeCode: activeCode });
4400     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4401         document.getElementById(yy.flashId).IYY_OnActive(activeCode);
4402     }
4403 }
4404 
4405 
4406 //-----------------------语音设备更换[Event]----------------------
4407 /**
4408 * 录音错误事件。
4409 * @param {Number} err_code 录音错误代码,参考错误代码表。
4410 * @private
4411 */
4412 function IAudioEvent_OnRecordErr(err_code) {
4413     if (debugMode) {
4414         yytrace(IYYAudio.RECORD_ERR + ":" + err_code);
4415     }
4416     yy.audio.dispatchEvent(IYYAudio.RECORD_ERR, { errCode: err_code });
4417     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4418         document.getElementById(yy.flashId).IAudioEvent_OnRecordErr(err_code);
4419     }
4420 }
4421 
4422 
4423 /**
4424 * 录音完成事件。
4425 * @param {String} info 录音完成信息。
4426 * @example 
4427 * 返回参数示例: {result:0,file_name:"abcd"} 
4428 * result 录音是否成功 0成功,非0值失败。
4429 * file_name 录音文件的名称,不带没有扩展名和路径。
4430 * @private
4431 */
4432 function IAudioEvent_OnRecordFinished(info) {
4433     if (debugMode) {
4434         yytrace(IYYAudio.RECORD_FINISHED + ":" + info);
4435     }
4436     var retJson = eval("(" + info + ")");
4437     yy.audio.dispatchEvent(IYYAudio.RECORD_FINISHED, { result: retJson.result, fileName: retJson.file_name });
4438     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4439         document.getElementById(yy.flashId).IAudioEvent_OnRecordFinished(retJson);
4440     }
4441 }
4442 
4443 //-----------------------频道信息获取回调接口 [Event]----------------------
4444 /**
4445 * 子频道跳转事件。
4446 * @param {String} info 频道跳转信息,是一个可以转成Json的字符串。
4447 * @example
4448 * 返回参数示例: {departed_id:15488855,now_id:85526655}
4449 * departed_id 原来子频道id。
4450 * now_id 现在子频道id。
4451 * @private
4452 */
4453 
4454 function IChannelEvent_OnFocusChannelChannged(info) {
4455     if (debugMode) {
4456         yytrace(IYYChannel.FOCUS_CHANNEL_CHANGED + ":" + info);
4457     }
4458     var retJson = eval("(" + info + ")");
4459     yy.channel.dispatchEvent(IYYChannel.FOCUS_CHANNEL_CHANGED, { departedId: retJson.departed_id, nowId: retJson.now_id });
4460     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4461         document.getElementById(yy.flashId).IChannelEvent_OnFocusChannelChannged(retJson);
4462     }
4463 }
4464 
4465 /**
4466 * 当前频道信息改变事件。
4467 * @param {String} info 改变后的频道信息,是一个可以转成Json的字符串。
4468 * @example
4469 * 返回参数示例: 
4470 *
4471 * {"ret":0,"long_id":51285414,"short_id":6048,"name":"月光酒吧"}
4472 *
4473 * ret 返回码 
4474 * long_id 频道长位id
4475 * short_id 频道短位id
4476 * name 频道名称id
4477 * @private
4478 */
4479 function IChannelEvent_OnChannelInfoChannged(info) {
4480     if (debugMode) {
4481         yytrace(IYYChannel.CHANNEL_INFO_CHANGED + ":" + info);
4482     }
4483     var retJson = eval("(" + info + ")");
4484     yy.channel.dispatchEvent(IYYChannel.CHANNEL_INFO_CHANGED, parseChannelInfo(retJson));
4485     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4486         document.getElementById(yy.flashId).IChannelEvent_OnChannelInfoChannged(retJson);
4487     }
4488 }
4489 
4490 
4491 
4492 
4493 
4494 /**
4495 * 删除子频道时产生事件。
4496 * @param {Number} cid 被删除的子频道长位id。
4497 * @private
4498 */
4499 function IChannelEvent_OnSubChannelDel(cid) {
4500     if (debugMode) {
4501         yytrace(IYYChannel.SUB_CHANNEL_DEL + ":" + cid);
4502     }
4503     yy.channel.dispatchEvent(IYYChannel.SUB_CHANNEL_DEL, { cid: cid });
4504     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4505         document.getElementById(yy.flashId).IChannelEvent_OnSubChannelDel(cid);
4506     }
4507 }
4508 
4509 
4510 /**
4511 * 添加子频道时产生事件。
4512 * @param {String} info 频道添加的信息,是一个可以转成Json的字符串。
4513 * @example 
4514 * 返回参数示例: {cid:15488855,pcid:85526655} 
4515 * cid 增加的子频道长位id。
4516 * pcid 增加到哪个父频道下,长位id。
4517 * @private
4518 */
4519 function IChannelEvent_OnSubChannelAdd(info) {
4520     if (debugMode) {
4521         yytrace(IYYChannel.SUB_CHANNEL_ADD + ":" + info);
4522     }
4523     var retJson = eval("(" + info + ")");
4524     yy.channel.dispatchEvent(IYYChannel.SUB_CHANNEL_ADD, { cid: retJson.cid, pcid: retJson.pcid });
4525     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4526         document.getElementById(yy.flashId).IChannelEvent_OnSubChannelAdd(retJson);
4527     }
4528 }
4529 /**
4530 
4531 * 用户进入大频道事件,子频道之间跳转不会触发此事件。
4532 * @param {String} info 用户加入频道的信息
4533 * @example 
4534 * 返回参数示例: {uid:905488855,cid:85526655} 
4535 * uid 进入的用户的uid。
4536 * cid 进入时进入到大频道中的哪个频道。
4537 * @private
4538 */
4539 function IChannelEvent_OnUserEnterChannel(info) {
4540     if (debugMode) {
4541         yytrace(IYYChannel.USER_ENTER_CHANNEL + ":" + info);
4542     }
4543     var retJson = eval("(" + info + ")");
4544     yy.channel.dispatchEvent(IYYChannel.USER_ENTER_CHANNEL, { uid: retJson.uid, cid: retJson.cid });
4545     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4546         document.getElementById(yy.flashId).IChannelEvent_OnUserEnterChannel(retJson);
4547     }
4548 }
4549 
4550 /**
4551 * 用户离开大频道事件,子频道之间跳转不会触发此事件。
4552 * @param {String} info 用户离开频道的信息
4553 * @example 
4554 * 返回参数示例: {uid:905488855,cid:85526655} 
4555 * uid 离开的用户的uid。
4556 * cid 离开大频道时所处的频道。
4557 * @private
4558 */
4559 function IChannelEvent_OnUserLeaveChannel(info) {
4560     if (debugMode) {
4561         yytrace(IYYChannel.USER_LEAVE_CHANNEL + ":" + info);
4562     }
4563     var retJson = eval("(" + info + ")");
4564     yy.channel.dispatchEvent(IYYChannel.USER_LEAVE_CHANNEL, { uid: retJson.uid, cid: retJson.cid });
4565     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4566         document.getElementById(yy.flashId).IChannelEvent_OnUserLeaveChannel(retJson);
4567     }
4568 }
4569 
4570 
4571 
4572 ///
4573 //------------------------频道用户列表右键菜单事件通知 [Event]
4574 ///
4575 /**
4576 * 频道用户列表右键菜单项被点击事件。
4577 * @param {String} info 点击用户的信息。
4578 * @example 
4579 * 返回参数示例: {uid:905488855,cid:85526655} 
4580 * uid 被点中的用户uid。
4581 * cid 当前所在的频道。
4582 * @private
4583 */
4584 function IChannelUserPopMenuEvent_OnClicked(info) {
4585     if (debugMode) {
4586         yytrace(IYYChannelUserListPopMenu.CLICKED + ":" + info);
4587     }
4588     var retJson = eval("(" + info + ")");
4589     yy.channel.userListPopMenu.dispatchEvent(IYYChannelUserListPopMenu.CLICKED, { uid: retJson.uid, cid: retJson.cid });
4590     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4591         document.getElementById(yy.flashId).IChannelUserPopMenuEvent_OnClicked(retJson);
4592     }
4593 }
4594 
4595 ///
4596 //------------------------网络状态回调 [Event]
4597 ///
4598 
4599 
4600 /**
4601 * 连接成功的事件。
4602 * @param {Number} result 0成功,非0值失败。
4603 * @private
4604 */
4605 /*
4606 function INetEvent_OnConnected(result) {
4607 yy.net.dispatchEvent(IYYNet.CONNECTED, { result: result });
4608 }*/
4609 
4610 
4611 /**
4612 * 连接断开后事件。
4613 * @param {Number} result 0:主动断开, 其他错误参考错误代码表
4614 * @private
4615 */
4616 
4617 function INetEvent_OnClosed(result) {
4618     if (debugMode) {
4619         yytrace(IYYNet.CLOSED + ":" + result);
4620     }
4621     yy.net.dispatchEvent(IYYNet.CLOSED, { result: result });
4622     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4623         document.getElementById(yy.flashId).INetEvent_OnClosed(result);
4624     }
4625 }
4626 
4627 
4628 /**
4629 * 收到广播数据包事件。
4630 * @param {Object} data 收到数据
4631 * @private
4632 */
4633 function INetEvent_OnRecv(data) {
4634     if (debugMode) {
4635         yytrace(IYYNet.RECV + ":" + data);
4636     }
4637     yy.net.dispatchEvent(IYYNet.RECV, { data: decodeURI(data) });
4638     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4639         document.getElementById(yy.flashId).INetEvent_OnRecv(data);
4640     }
4641 }
4642 
4643 
4644 ///
4645 //------------------------------------------频道应用信息链接事件 [Event]
4646 ///
4647 
4648 
4649 /**
4650 * 应用消息中的链接被点击事件。
4651 * @param {Number} token 消息标记,区分不同的消息。
4652 * @private
4653 */
4654 function IChannelAppLinkEvent_OnAppLinkClicked(token) {
4655     if (debugMode) {
4656         yytrace(IYYChannelAppMsg.APP_LINK_CLICKED + ":" + token);
4657     }
4658     yy.channel.appMsg.dispatchEvent(IYYChannelAppMsg.APP_LINK_CLICKED, { token: token });
4659     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4660         document.getElementById(yy.flashId).IChannelAppLinkEvent_OnAppLinkClicked(token);
4661     }
4662 }
4663 /**
4664 * @private
4665 */
4666 function IChannelAppLinkEvent_OnAppLinkExClicked(token, userData) {
4667     if (debugMode) {
4668         yytrace(IYYChannelAppMsg.APP_LINK_EX_CLICKED + ":" + token + " " + userData);
4669     }
4670     yy.channel.appMsg.dispatchEvent(IYYChannelAppMsg.APP_LINK_EX_CLICKED, { token: token, userData: userData });
4671     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4672         document.getElementById(yy.flashId).IChannelAppLinkEvent_OnAppLinkExClicked(token, userData);
4673     }
4674 }
4675 
4676 ///
4677 //------------------------------------------麦序相关接口事件
4678 ///
4679 
4680 //麦序列表发生改变
4681 
4682 
4683 /**
4684 * 用户加入到麦序事件。
4685 * @param {uid} 加入到麦序的用户uid。
4686 * @private
4687 */
4688 function IMicListEvent_OnUserJoin(uid) {
4689     if (debugMode) {
4690         yytrace(IYYChannelMicList.USER_JOIN + ":" + uid);
4691     }
4692     yy.channel.micList.dispatchEvent(IYYChannelMicList.USER_JOIN, { uid: uid });
4693     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4694         document.getElementById(yy.flashId).IMicListEvent_OnUserJoin(uid);
4695     }
4696 }
4697 /**
4698 * 用户离开麦序事件。
4699 * @param {Number} uid 离开麦序的用户uid。
4700 * @private
4701 */
4702 function IMicListEvent_OnUserLeave(uid) {
4703     if (debugMode) {
4704         yytrace(IYYChannelMicList.USER_LEAVE + ":" + uid);
4705     }
4706     yy.channel.micList.dispatchEvent(IYYChannelMicList.USER_LEAVE, { uid: uid });
4707     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4708         document.getElementById(yy.flashId).IMicListEvent_OnUserLeave(uid);
4709     }
4710 }
4711 /**
4712 * 用户在麦序中的位置发生变化事件,同一子频道的用户会收到。
4713 * @example 
4714 * 返回参数示例: {move_id:905488855,to_after_id:905477756} 
4715 * move_id:发生移动的id。
4716 * to_after_id:移动到那个用户后面。
4717 * @private
4718 */
4719 function IMicListEvent_OnUserMove(info) {
4720     if (debugMode) {
4721         yytrace(IYYChannelMicList.USER_MOVE + ":" + info);
4722     }
4723     var retJson = eval("(" + info + ")");
4724     yy.channel.micList.dispatchEvent(IYYChannelMicList.USER_MOVE, { moveId: retJson.move_id, toAfterId: retJson.to_after_id });
4725     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4726         document.getElementById(yy.flashId).IMicListEvent_OnUserMove(retJson);
4727     }
4728 }
4729 
4730 /**
4731 * 麦序被清除事件。
4732 * @private
4733 */
4734 function IMicListEvent_OnClear() {
4735     if (debugMode) {
4736         yytrace(IYYChannelMicList.CLEAR);
4737     }
4738     yy.channel.micList.dispatchEvent(IYYChannelMicList.CLEAR);
4739     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4740         document.getElementById(yy.flashId).IMicListEvent_OnClear();
4741     }
4742 }
4743 /**
4744 * @private
4745 */
4746 function IChannelMicList_OnUserMicLinked(uid) {
4747     if (debugMode) {
4748         yytrace(IYYChannelMicList.USER_LINKED + ":" + uid);
4749     }
4750     yy.channel.micList.dispatchEvent(IYYChannelMicList.USER_LINKED, { uid: uid });
4751     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4752         document.getElementById(yy.flashId).IChannelMicList_OnUserMicLinked(uid);
4753     }
4754 }
4755 /**
4756 * @private
4757 */
4758 function IChannelMicList_OnUserMicUnlinked(uid) {
4759     if (debugMode) {
4760         yytrace(IYYChannelMicList.USER_UNLINKED + ":" + uid);
4761     }
4762     yy.channel.micList.dispatchEvent(IYYChannelMicList.USER_UNLINKED, { uid: uid });
4763     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4764         document.getElementById(yy.flashId).IChannelMicList_OnUserMicUnlinked(uid);
4765     }
4766 }
4767 /**
4768 * @private
4769 */
4770 function IChannelMicList_OnMicListModeChanged(mode) {
4771     if (debugMode) {
4772         yytrace(IYYChannelMicList.MODE_CHANGED + ":" + mode);
4773     }
4774     yy.channel.micList.dispatchEvent(IYYChannelMicList.MODE_CHANGED, { mode: mode });
4775     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4776         document.getElementById(yy.flashId).IChannelMicList_OnMicListModeChanged(mode);
4777     }
4778 }
4779 //-------------------
4780 
4781 /**
4782 * @private
4783 */
4784 function IChannelMicList_OnMicListControlled(adminUid) {
4785     if (debugMode) {
4786         yytrace(IYYChannelMicList.CONTROLLED + ":" + adminUid);
4787     }
4788     yy.channel.micList.dispatchEvent(IYYChannelMicList.CONTROLLED, { adminUid: adminUid });
4789     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4790         document.getElementById(yy.flashId).IChannelMicList_OnMicListControlled(adminUid);
4791     }
4792 }
4793 /**
4794 * @private
4795 */
4796 function IChannelMicList_OnMicListReleased(adminUid) {
4797     if (debugMode) {
4798         yytrace(IYYChannelMicList.RELEASED + ":" + adminUid);
4799     }
4800     yy.channel.micList.dispatchEvent(IYYChannelMicList.RELEASED, { adminUid: adminUid });
4801     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4802         document.getElementById(yy.flashId).IChannelMicList_OnMicListReleased(adminUid);
4803     }
4804 }
4805 /**
4806 * @private
4807 */
4808 function IChannelMicList_OnDisableJoinMicList(adminUid) {
4809     if (debugMode) {
4810         yytrace(IYYChannelMicList.DISABLE_JOIN + ":" + adminUid);
4811     }
4812     yy.channel.micList.dispatchEvent(IYYChannelMicList.DISABLE_JOIN, { adminUid: adminUid });
4813     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4814         document.getElementById(yy.flashId).IChannelMicList_OnDisableJoinMicList(adminUid);
4815     }
4816 }
4817 /**
4818 * @private
4819 */
4820 function IChannelMicList_OnEnableJoinMicList(adminUid) {
4821     if (debugMode) {
4822         yytrace(IYYChannelMicList.ENABLE_JOIN + ":" + adminUid);
4823     }
4824     yy.channel.micList.dispatchEvent(IYYChannelMicList.ENABLE_JOIN, { adminUid: adminUid });
4825     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4826         document.getElementById(yy.flashId).IChannelMicList_OnEnableJoinMicList(adminUid);
4827     }
4828 }
4829 /**
4830 * @private
4831 */
4832 function IChannelMicList_OnMicListTimeChanged(adminUid,uid,seconds) {
4833     if (debugMode) {
4834         yytrace(IYYChannelMicList.TIME_CHANGED +":adminUid="+adminUid+" uid="+uid+ " seconds=" + seconds);
4835     }
4836     yy.channel.micList.dispatchEvent(IYYChannelMicList.TIME_CHANGED, { adminUid: adminUid, uid: uid, seconds: seconds });
4837     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4838         document.getElementById(yy.flashId).IChannelMicList_OnMicListTimeChanged(adminUid, uid, seconds);
4839     }
4840 }
4841 /**
4842 * @private
4843 */
4844 function IChannelMicList_OnSpeakingStateChanged(uid, speaking) {
4845     if (debugMode) {
4846         yytrace(IYYChannelMicList.SPEAKING_STATE_CHANGED + ":" + uid + " " + speaking);
4847     }
4848     yy.channel.micList.dispatchEvent(IYYChannelMicList.SPEAKING_STATE_CHANGED, { uid: uid, speaking: speaking });
4849     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4850         document.getElementById(yy.flashId).IChannelMicList_OnSpeakingStateChanged(uid, speaking);
4851     }
4852 }
4853 /**
4854 * @private
4855 */
4856 function IChannelMicList_OnMicListNotification(adminUid) {
4857     if (debugMode) {
4858         yytrace(IYYChannelMicList.NOTIFICATION + ":" + adminUid);
4859     }
4860     yy.channel.micList.dispatchEvent(IYYChannelMicList.NOTIFICATION, { adminUid: adminUid });
4861     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4862         document.getElementById(yy.flashId).IChannelMicList_OnMicListNotification(adminUid);
4863     }
4864 }
4865 //----------------------------用户事件回调------------------------------------------
4866 /**
4867 * 用户信息改变事件,得到改变后的用户信息。
4868 * @param {String} info 改变后的用户信息,是一个可以转成Json的字符串。
4869 * @private
4870 */
4871 function IUserEvent_OnUserInfoChanged(info) {
4872     if (debugMode) {
4873         yytrace(IYYUser.USER_INFO_CHANGED+":"+info);
4874     }
4875     var retJson = eval("(" + info + ")");
4876     yy.user.dispatchEvent(IYYUser.USER_INFO_CHANGED, parseUserInfo(retJson));
4877     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4878         document.getElementById(yy.flashId).IUserEvent_OnUserInfoChanged(retJson);
4879     }
4880 }
4881 
4882 /**
4883 * 转换频道信息格式。频道信息完整的时候使用
4884 * @private
4885 */
4886 function parseChannelInfo(info) {
4887     var cinfo = {};//= new YYChannelInfo();
4888     cinfo.ret = 0;
4889     cinfo.longId = info.long_id;
4890     cinfo.shortId = info.short_id;
4891     cinfo.name = unescape(info.name);
4892     cinfo.userCount = info.user_count;
4893     cinfo.totalUserCount = info.total_user_count;
4894     cinfo.channelType = info.channel_type;
4895     cinfo.channelPoints = info.channel_points;
4896     return cinfo;
4897 }
4898 
4899 /**
4900 * 转换用户信息格式。用户信息完整的时候使用
4901 * @private
4902 */
4903 function parseUserInfo(info) {
4904     var userInfo = {};// new YYUserInfo();
4905     userInfo.ret = 0;
4906     userInfo.uid = info.uid;
4907     userInfo.name = unescape(info.name);
4908     userInfo.imId = info.imid;
4909     userInfo.role = info.role;
4910     userInfo.points = info.points;
4911     userInfo.level = info.level;
4912     userInfo.sex = info.sex;
4913     userInfo.sign = unescape(info.sign);
4914     userInfo.vip = info.vip;
4915     userInfo.vipLevel = info.vip_level;
4916     userInfo.contribution = info.contribution;
4917     return userInfo;
4918 }
4919 /**
4920 * 转换用户信息格式。
4921 * @private
4922 */
4923 function parseCloudDataList(data) {
4924     var dataArray = [];
4925     for (var i = 0; i < data.length; i++) {
4926         var dt = {};
4927         dt.key = data[i].key;
4928         dt.createTime = data[i].create_time;
4929         dt.updateTime = data[i].update_time;
4930         dt.creatorUid = data[i].creator_uid;
4931         dt.intValue1 = data[i].int1;
4932         dt.intValue2 = data[i].int2;
4933         dt.stringValue = data[i].str;
4934         dataArray.push(dt);
4935     }
4936 
4937     return dataArray;
4938 }
4939 //----------------------------临时语音事件回调------------------------------------------
4940 /**
4941 * 用户进入房间。
4942 * @private
4943 */
4944 function ITempAudioSession_OnUserEnterRoom(info) {
4945     if (debugMode) {
4946         yytrace(IYYTempAudioSession.USER_ENTER_ROOM + ":" + info);
4947     }
4948     var retJson = eval("(" + info + ")");
4949     yy.tempAudioSession.dispatchEvent(IYYTempAudioSession.USER_ENTER_ROOM, { rid: retJson.rid, uid: retJson.uid });
4950     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4951         document.getElementById(yy.flashId).ITempAudioSession_OnUserEnterRoom(retJson);
4952     }
4953 }
4954 /**
4955 * 用户离开房间。
4956 * @private
4957 */
4958 function ITempAudioSession_OnUserLeaveRoom(info) {
4959     if (debugMode) {
4960         yytrace(IYYTempAudioSession.USER_LEAVE_ROOM + ":" + info);
4961     }
4962     var retJson = eval("(" + info + ")");
4963     yy.tempAudioSession.dispatchEvent(IYYTempAudioSession.USER_LEAVE_ROOM, { rid: retJson.rid, uid: retJson.uid });
4964     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4965         document.getElementById(yy.flashId).ITempAudioSession_OnUserLeaveRoom(retJson);
4966     }
4967 }
4968 
4969 
4970 function ITempAudioSession_OnSpeakerChanged(info) {
4971     if (debugMode) {
4972         yytrace(IYYTempAudioSession.SPEAKER_CHANGED + ":" + info);
4973     }
4974     var retJson = eval("(" + info + ")");
4975     yy.tempAudioSession.dispatchEvent(IYYTempAudioSession.SPEAKER_CHANGED, { speakerList: retJson.speaker_list.concat() });
4976     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4977         document.getElementById(yy.flashId).ITempAudioSession_OnSpeakerChanged(retJson);
4978     }
4979 }
4980 //----------------------------财务接口回调------------------------------------------
4981 /**
4982 * @private
4983 */
4984 function IFinanceEvent_OnBuyResponse(info) {
4985     if (debugMode) {
4986         yytrace(IYYFinance.BUY_RESPONSE + ":" + info);
4987     }
4988     var retJson = eval("(" + info + ")");
4989     yy.finance.dispatchEvent(IYYFinance.BUY_RESPONSE, { sn: retJson.sn, ret: retJson.ret, mode: retJson.mode });
4990     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
4991         document.getElementById(yy.flashId).IFinanceEvent_OnBuyResponse(retJson);
4992     }
4993 }
4994 /**
4995 * @private
4996 */
4997 function IFinanceEvent_OnBuyGiftsResponse(info) {
4998     if (debugMode) {
4999         yytrace(IYYFinance.BUY_GIFTS_RESPONSE + ":" + info);
5000     }
5001     var retJson = eval("(" + info + ")");
5002     yy.finance.dispatchEvent(IYYFinance.BUY_GIFTS_RESPONSE, { sn: retJson.sn, ret: retJson.ret, mode: retJson.mode });
5003     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
5004         document.getElementById(yy.flashId).IFinanceEvent_OnBuyGiftsResponse(retJson);
5005     }
5006 }
5007 //----------------------------公屏回调------------------------------------------
5008 
5009 /**
5010 * @private
5011 */
5012 function IChannelChat_OnChat(uid, msg) {
5013     if (debugMode) {
5014         yytrace(IYYChannelChat.CHAT + ":uid=" + uid + " msg=" + msg);
5015     }
5016     yy.channel.chat.dispatchEvent(IYYChannelChat.CHAT, { uid: uid, msg: msg });
5017     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
5018         document.getElementById(yy.flashId).IChannelChat_OnChat(uid, msg);
5019     }
5020 }
5021 /**
5022 * @private
5023 */
5024 function IChannelChat_OnChatFrom(uid, msg) {
5025     if (debugMode) {
5026         yytrace(IYYChannelChat.CHAT_FROM + ":uid=" + uid + " msg=" + msg);
5027     }
5028     yy.channel.chat.dispatchEvent(IYYChannelChat.CHAT_FROM, { uid: uid, msg: msg });
5029     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
5030         document.getElementById(yy.flashId).IChannelChat_OnChatFrom(uid, msg);
5031     }
5032 }
5033 
5034 //----------------------------视频接口回调------------------------------------------
5035 /**
5036 * @private
5037 */
5038 function IVideo_OnPublishStatus(status) {
5039     if (debugMode) {
5040         yytrace(IYYVideo.PUBLISH_STATUS + " status=" + status);
5041     }
5042     yy.video.dispatchEvent(IYYVideo.PUBLISH_STATUS, { status: status });
5043     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
5044         document.getElementById(yy.flashId).IVideo_OnPublishStatus(status);
5045     }
5046 }
5047 /**
5048 * @private
5049 */
5050 function IVideo_OnCameraStatus(status) {
5051     if (debugMode) {
5052         yytrace(IYYVideo.CAMERA_STATUS + " status=" + status);
5053     }
5054     yy.video.dispatchEvent(IYYVideo.CAMERA_STATUS, { status: status });
5055     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
5056         document.getElementById(yy.flashId).IVideo_OnCameraStatus(status);
5057     }
5058 }
5059 /**
5060 * @private
5061 */
5062 function IVideo_OnSubscribeStatus(uid, status) {
5063     if (debugMode) {
5064         yytrace(IYYVideo.SUBSCRIBE_STATUS + ":uid=" + uid + " status=" + status);
5065     }
5066     yy.video.dispatchEvent(IYYVideo.SUBSCRIBE_STATUS, { uid: uid, status: status });
5067     if (typeof (yy.flashId) === "string" && yy.flashId !== "") {
5068         document.getElementById(yy.flashId).IVideo_OnSubscribeStatus(uid, status);
5069     }
5070 }
5071 
5072 
5073 
5074 //调用数据统计
5075 /*
5076 var yyapi_call_stat = null;
5077 var yyapi_call_stat_buff = [];
5078 var yyapi_call_stat_cid = 0;
5079 var yyapi_call_stat_uid = 0;
5080 var yyapi_call_stat_handle = 0;
5081 
5082 var yyapi_call_stat_handle = setInterval(function () {
5083     //yytrace("***************************** stat init......");
5084     if (document.body != null) {
5085         yyapi_call_stat = document.createElement("img");
5086         yyapi_call_stat.id = "imgYYCallStat";
5087         yyapi_call_stat.style.position = "absolute";
5088         yyapi_call_stat.style.width = "50px";
5089         yyapi_call_stat.style.height = "50px";
5090         yyapi_call_stat.style.backgroundColor = "#FF0000";
5091         yyapi_call_stat.style.left = "300px";
5092         yyapi_call_stat.style.top = "0px";
5093         yyapi_call_stat.style.display = "none";
5094         var result = yy.channel.getRootChannelId();
5095         yyapi_call_stat_cid = result.ret == 0 ? result.cid : 0;
5096         result = yy.user.getCurrentUserInfo();
5097         yyapi_call_stat_uid = result.ret == 0 ? result.uid : 0;
5098         document.body.appendChild(yyapi_call_stat);
5099         clearInterval(yyapi_call_stat_handle);
5100         //yytrace("************************** stat init finish");
5101         while (yyapi_call_stat_buff.length > 0) {
5102             var tmp = yyapi_call_stat_buff.pop();
5103             yyapi_call_stat.src = "http://ylog.hiido.com/c.gif?" + tmp;
5104             //yytrace("buffer:" + yyapi_call_stat.src);
5105         }
5106        
5107     }
5108 }, 1000);
5109 
5110 
5111 function statisticApiCall(apiName,result)
5112 {
5113     var apiId = 0;
5114     switch (apiName) {
5115         case "ISecurity_GetToken":
5116             apiId = 9001;
5117             break;
5118         case "ITempAudioSession_CreateRoom":
5119             apiId = 1001;
5120             break;
5121         case "ITempAudioSession_EnterRoom":
5122             apiId = 1002;
5123             break;
5124         case "ITempAudioSession_LeaveRoom":
5125             apiId = 1003;
5126             break;
5127         case "IFinance_Buy":
5128             apiId = 501;
5129             break;
5130         case "IFinance_BuyByYuan":
5131             apiId = 502;
5132             break;
5133         case "IFinance_BuyGifts":
5134             apiId = 503;
5135             break;
5136         case "IInteraction_Invite":
5137             apiId = 7001;
5138             break;
5139         case "INet_BroadCastAllChannel":
5140             apiId = 8001;
5141             break;
5142         case "INet_BroadCastSubChannel":
5143             apiId = 8002;
5144             break;
5145         case "INet_BroadCastToUsers":
5146             apiId = 8003;
5147             break;
5148         default:
5149 
5150     }
5151 
5152     if (apiId == 0) return;
5153     var param = "act=webopenapi&type=0&appid=0&api_id=" + apiId + "&sid=" + yyapi_call_stat_cid + "&uid=" + yyapi_call_stat_uid + "&count=1&return=" + result.ret + "&desc=0";
5154     if (yyapi_call_stat == null) {
5155         yyapi_call_stat_buff.push(param);
5156         return;//初始化未完成
5157     }
5158 
5159     yyapi_call_stat.src = "http://ylog.hiido.com/c.gif?" + param;
5160     //yytrace(yyapi_call_stat.src);
5161     
5162 
5163 }
5164 */