# Tutorial: SDK 版本发布日志

## SDK 版本发布日志

版本号`major.minor.secondary.patch.temp`具体规则如下：

- major：主版本号，如有重大版本重构则该字段递增，通常各主版本间接口不兼容。
- minor：次版本号，各次版本号间接口基本保持兼容，偶有接口参数变化，需要调整等。
- secondary: 更次要版本号，各次版本号间接口保持兼容，如有接口新增或优化则该字段递增。
- patch：修订版本号，如有功能改善或缺陷修复则该字段递增。
- temp：临时版本号, 通常是内部测试或紧急修复的版本。这个版本号可以根据需要进行更新。

> 注意：

> - 建议您及时更新至最新版本，以便获得更好的产品稳定性及在线支持。
> - 版本升级注意事项请参见：升级指引。

## Version 4.0.8.3

Feature

- 新增常量：观察者用户的user_agent值，var USER_AGENT_AVD_COVERT_VIEWER = "avd_covert_viewer"

Improvement

- 浏览器检测接口中增加对华为鸿蒙OpenHarmony的支持
- 浏览器检测接口中新增对钉钉内置浏览器的支持

Bug Fixed

- 修复messageManager.js中case roomPduType.UPDATE_WEBCAM_MSG部分设备id获取错的bug
- 修复4.0.8.1版本引入的订阅共享屏幕音频听不到的bug。

## Version 4.0.8.2

Feature

- 新增设置及获取桌面共享弹窗显示内容选项的二个接口:screen.setDisplaySurface(ScreenDisplaySurface.monitor) 和screen.getDisplaySurface()。
- 新增获取房间参会者人数接口room.getParticipantsNumber()。
- 新增设置RESTful API请求类型的接口: avdEngine.setRestfulRequestType(1);0 表示GET; 1表示 POST，默认为0。当设置成POST类型时,sdk内部所有调用的RESTful API请求都采用POST类型。
- 新增获取房间内当前白板数接口:room.getBoardNumber(status)。参数status可以不填，不填时包括状态值为boardStatusEnum.open和boardStatusEnum.close的所有白板数。

Improvement

- 新增上报服务器PDU OpenReq中的video_codec_rtx_map,用于优化下行订阅端视频高丢包率的问题。

- 白板图片拖动中,区域位置不能移出白板之外,放大缩小图片及重设置白板宽高后还有效。

- 用户离会及关闭会议前如有打开过白板,会先删除掉白板。

- 针对用户异常离会、被踢、重新加会等等异常case,完善白板的功能：

  - 当本地网络不好重新加会时,如房间里一个人都没有时,服务器会销毁白板及批注相关信息。 重新加会成功后需要再次上报白板及批注信息给服务器,否则会议里新加入用户因服务器不下发白板及批注信息，而看不到白板及批注。
  - 应用层在RoomCallback.user_leave_notify的回调里,reason=804时(当同一个userid加会,把前一个人踢下线), 白板界面什么都不需要处理。
  - 应用层在RoomCallback.user_leave_notify的回调里,reason=808时(当用户被SDK接口踢掉及被外部调用restful接口踢掉或restful接口关闭会议),删除白板相关的界面。
  - 应用层在RoomCallback.user_leave_notify的回调里,reason=812时(用户心跳超时掉线【如异常退会或网络不好重新加会】),应用层隐藏该用户的白板界面。
  - 应用层在RoomCallback.user_join_notify的回调里,如果用户的白板存在且刚好是隐藏的白板,应用层显示该用户的白板界面。
  - 应用层在(RoomCallback.connection_status的回调里,当status == ConnectionStatus.reJoinConnected时(重新加会成功),应用层根据room.cleanupBoardByReJoinConnected为true及当前房间参数人数大于1人时，删除白板相关的界面.
  - 应用层当创建自己的白板时或收到远端创建白板时,需要先删除本地原来隐藏的所有白板。

        roomClient.addCallback(RoomCallback.connection_status, onConnectionStatus);
        roomClient.addCallback(RoomCallback.user_leave_notify, onUserLeaveNotify);
        roomClient.addCallback(RoomCallback.user_join_notify, onUserJoinNotify);

        function onConnectionStatus(status) {
      	  if(status == ConnectionStatus.reJoinConnected){
      		setTimeout(function(){
      			  //重新加会成功后，应用层根据room.cleanupBoardByReJoinConnected为true及当前房间参数人数大于1人时，删除白板相关的界面.
      			  if(roomClient.cleanupBoardByReJoinConnected && roomClient.getParticipants().length>1){
      				 //原来的白板内容清场
      				 removeBoardHandle(currentBoardId);
      			  }
      		},500);
      	  }
        }

        function onUserLeaveNotify(opt, reason, user) {
      	  //当同一个userid加会,把前一个人踢下线,收到804报错时，白板界面什么都不需要处理
      	  if(reason == 804){
      	  }

      	  //当用户被SDK接口踢掉及被外部调用restful接口踢掉或restful接口关闭会议报808错误时，应用层删除白板界面
      	  if(reason == 808){
      	  	if(user.boards && user.boards.length>0 ){
      	  		for(var key in user.boards) {
      	  			var board = user.boards[key];
      	  			removeBoardHandle(board.id);
      	  		}
      	  	}
      	  }

      	  //用户心跳超时掉线（如异常退会，或网络不好重新加会）,应用层隐藏该用户的白板界面
      	  if(reason == 812){
      	    if(user.boards && user.boards.length>0 ){
      	       	for(var key in user.boards) {
      	       		var board = user.boards[key];
      	       		hideBoardHandle(user.id, board.id);
      	       	}
      	    }
      	  }
        }

        function onUserJoinNotify(users) {
      	  users.forEach(function(user) {
      		  //用户的白板存在且刚好是隐藏的白板，应用层显示该用户的白板界面
      		  var boards = user.boards;
      		  if(boards && boards.length > 0) {
      			for(key in boards) {
      				var board = boards[key];
      				var str = user.id+"__"+board.id;
      				if(hideBoardIds.includes(str)){
      					displayBoardHandle(user.id, board.id);
      				}
      			}
      		  }
      	});
        }

        //应用层创建白板
        function createBoardHandle(board) {
      	//应用层当创建自己的白板时或收到远端创建白板时，需要先删除本地原来隐藏的所有白板
        	if(hideBoardIds &&  hideBoardIds.length>0){
        		 for(var i = 0; i < hideBoardIds.length; i++) {
        			var hideBoardId = hideBoardIds[i];
        			var splitted = hideBoardId.split("__");
        			var userId = splitted[0];
        			var boardId = splitted[1];
        			roomClient.selfUser.removeBoardById(boardId, userId).then(function(){
        			    console.log('应用层原来隐藏的白板删除成功');
        				removeBoardHandle(boardId);
        			}).otherwise(function(err){
        				console.log('应用层原来隐藏的白板删除失败,err:',err);
        			});
        		 }
        	}
      	...
       }

Bug Fixed

- 修复更新用户名称接口及回调无效的bug, 接口为user.updateUserName(userName).

## Version 4.0.8.1

Feature

- 新增导入第三方音视频流功能
  - 新增接口 '创建一个自定义的视频轨道': user.createCustomVideoTrack(mediaStreamTrack, trackName).then(function(video){})。
  - 新增接口 '删除一个自定义的视频轨道': user.deleteCustomVideoTrack(videoId).then(function(){})。
  - 新增接口 '创建一个自定义的音频轨道': user.createCustomAudioTrack(mediaStreamTrack, trackName).then(function(audio){})。
  - 新增接口 '删除一个自定义的音频轨道': user.deleteCustomAudioTrack(audioId).then(function(){})。

Improvement

- 白板相关逻辑优化

  - 创建白板接口user.createBoard()在服务器版本为<3.1.7时，内部二方法之间做了延时处理，已保证订阅端收到add及share的PDU时序不乱。

  - 更新白板接口user.updateBoard(board) 改成异步方法user.updateBoard(board).then(function(){})。

  - 删除白板接口user.removeBoardById(boardId) 改成异步方法user.removeBoardById(boardId).then(function(){})。

  - 关闭共享白板接口user.closeBoardById(boardId) 改成异步方法user.closeBoardById(boardId).then(function(){})。

  - 共享白板接口user.shareBoardById(boardId) 改成异步方法user.shareBoardById(boardId).then(function(){})。

  - 新提供布尔型方法属性room.cleanupBoardByReJoinConnected, 用于确认应用层在重新加会成功后需不需要清除原来的白板相关界面内容。

        function onConnectionStatus(status) {
          if(status == ConnectionStatus.reJoinConnected) {
          	 //重新加会成功后，应用层根据该字段确认需要清理白板相关界面内容
          	 if(roomClient.cleanupBoardByReJoinConnected){
          		 //todo 原有的白板内容界面清场
          	 }
          }
        }

  - 从该版本起白板发起端做了PDU时序保障，所以本版本订阅端不再维护add /share，remove/close这二个时序对列。但老版本的各客户端发起的白板,订阅端会有小概率的时序问题，建议各客户端都同步升级下。

Bug Fixed

- 关于二次重新加会之间间隔（默认时长3秒),修复在重新加会超时时长（默认60秒）超时之前也生效。
- 修复4.0.7.0引入的白板激光笔失效的bug
- 修复4.0.7.9引入的白板橡皮擦失效的bug

## Version 4.0.8.0

Feature

- 新增接口avdEngine.setCustomerTokenEnabled(true),设置启用客户自己的认证token，且认证token在协议请求头中传递。

Improvement

- util.getGPUInfo()方法加上try/catch，以防止有些机子不支持GPU型号的检测而报错。
- 引用第三方的包ua-parser.min.js版本从v0.7.31升级到v2.0.0-beta.3,原因v1.0.3.3之前的版本存在安全漏洞(ReDoS).

Bug Fixed

- 修复本端多次切换麦克风设备，远端SDP报错的问题。
- 修复重启MCU后白板显示相关的问题。

## Version 4.0.7.9

Feature

- 新增应用层自定义RestFull访问时应用协议，替换默认的document.location.protocol,提供接口avdEngine.setRestFullProtocol("https:");
- 新增发送私有二进制数据接口及回调方法。room.sendPrivateDataToUser(dataBinary, userId);roomClient.addCallback(RoomCallback.private_data_to_user, onPrivateDataToUser);function onPrivateDataToUser(dataArrayBuffer, userId) {}

Improvement

- 因客户应用层可能通过Array.prototype 添加过新方法，这些方法也会被添加到所有数组实例的原型链上。SDK中通过for in循环遍历数组时，它不仅会遍历数组的元素，还会遍历到新添加的方法,这可能会导致一些意外的行为。所以把 for in 循环全改成Array.forEach() 方法来遍历数组。

Bug Fixed

- 白板相关的bug修复(4.0.7.8引入的)，重现case: A用户创建白板后关闭白板之后，B用户加入会议，A用户打开白板，B用户看不到该白板。
- client类中原生对象的原型操作Array.prototype.contains改成工具函数arrayUtil.contains，以避免原型污染。

## Version 4.0.7.8

Feature

- 新增白板授权校验功能，因客户端与服务器端都有新增PDU，客户端有做兼容老服务器版本的处理。应用层在调用user.createBoard时，该方法变成异步方法.即room.selfUser.createBoard(boardWidth, boardHeight, backgroundColor, backgroundImage,'',boardWidth,boardHeight).then(function(board){}).otherwise(function(err){})。
- 新增媒体数据包的总量化值(qpSum)、每个视频帧的平均量化值(perFrameQP)、已编码帧的数量(framesEncoded)、已解码帧的数量(framesDecoded)等网络状态值获取。
- 新增二次重新加会之间设置默认间隔时长3秒,以免太频繁引发服务器的黑名单机制。且新增接口room.setRejoinInterval(rejoinInterval)设置自定义的间隔时长。

Improvement

- 优化白板信令时序逻辑
- 优化重构网络状态值(重点是房间级别的上下行丢包数/丢包率,发布及订阅媒体的丢包数/丢包率).
- 设备插拔后SDK除上报给应用层状态变化的设备ID集接口回调外，内部会自主处理上报或删除给服务器的设备集,另如当前被拔的设备正好是正在使用发布流的设备，会自动取消发布及关闭的处理。建议以后不再 使用avdEngine.refreshDevice()这个设备热插拔时手动刷新设备的接口。
- 麦克风和扬声器设备的获取逻辑有变化，已避免获取到id为default的设备，否则插拔时会有问题。

Bug Fixed

- 修复mcu重启后，白板的图片缩放起始点异常和图片没有lineColor报错的问题
- 修复room.js中方法audioLevelHandler的statsInterval属性定义有误的问题。这会引发佳会中语音激励不准。

## Version 4.0.7.7

Bug Fixed

- 修复重连过程中客户端发给服务器的OPEN_REQ,服务器未响应返的超时处理问题
- 修复桌面共享没有授权抛错时，桌面共享状态没取消显示的问题
- Chrome126开始SDP ssrc片段中不含有msid信息，引发服务器解析失败及其它客户端crash，SDK做兼容处理。

## Version 4.0.7.6

Feature

- 重新加会成功后，之前发布的屏幕共享自动重新发布
- 房间透明通道发送数据大小限制到60K，避免数据过大导致websocket断开重连，且透明通道方法封装为异步，可将异常返回给应用层。
- websocket重连成功时，如之前和媒体服务器已经断开连接，则重新加会

## Version 4.0.7.5

Feature

- 新增接口"设置音频播放设备扬声器",room.setSpeakerDevice(deviceId, audioElements)
- 新增接口"设置扬声器音量大小",room.setSpeakerVolume(volume, audioElements);

Bug Fixed

- 修复重新加会后，网络状态变动过快的问题
- 修复当本地离开会议或关闭会议时偶现报错的问题
- 修复当本地离开会议或关闭会议时偶现音视频设备资源未释放的问题
- 修复当本地离开会议或关闭会议时偶现屏幕共享条未关闭的问题
- 修复addSdpHandle和reduceSdpHandle中关于Peerconnection设置与信令发送的时序问题

## Version 4.0.7.4

Feature

- 屏幕共享和用户音频区分
- 新增屏幕共享静音、取消静音接口
  - screen.muteScreenAudio()
  - screen.unmuteScreenAudio()
- 新增屏幕共享音频状态回调
  - user.addCallback(UserCallback.screen_audio_status_notify, onScreenAudioStatusNotify)
- 引擎级别新增setEnableHardwareEncoding接口，加入会议前设置是否开启硬件编码
  - avdEngine.setEnableHardwareEncoding(true)
  - 注：此功能推荐在使用独立显卡的电脑上开启，非独立显卡，例如使用CPU核显的电脑不推荐开启此功能

Bug Fixed

- 修复重新加会后偶现音视频发布失败的问题
- 修复electron发布屏幕共享publishHandle方法没有异步返回的问题

## Version 4.0.7.3

Feature

- 安卓Chrome浏览器支持解码H264视频，不需要服务器开启转码
- 引擎级别新增设置忽略服务器资源调整信令方法avdEngine.setIgnoreModifyResourceReq，默认值false，设置为true则本端发布的视频无人订阅时不会自动调整分辨率

Bug Fixed

- 修复iOS17.3.1 safari的音视频没有分辨率等统计信息的问题

## Version 4.0.7.2

Feature

- 支持音频流分离。将桌面共享的音频和用户的音频分离成两个不同的stream, 以解决ios safari等不能同时听到二类声音的问题。
- User类新增attachScreenAudioElementMediaStream方法，用于将屏幕共享音频流渲染进指定音频控件

Improvement

- 优化重新加会逻辑调整。room添加rejoinTimeout、currentRejoinTimeout、rejoinAlways控制重新加会。

Bug Fixed

- 修复创建带背景图背景色的白板时自动设置背景图。

## Version 4.0.7.1

Improvement

- 优化屏幕共享音频默认关闭回音消除。

## Version 4.0.7.0

Feature

- avdEngine内添加设置回声消除、噪声抑制、自动增益接口：
  - avdEngine.setEchoCancellation(true)
  - avdEngine.setNoiseSuppression(true)
  - avdEngine.setAutoGainControl(true)
- 白板：
  - 批注初始化方法annotation.init新增初始化类型AnnotationInitType参数，默认为AnnotationInitTypeEnum.full，填充整个外部容器，兼容以前的逻辑
  - 可选AnnotationInitTypeEnum.proportional，可以按比例渲染远端白板

Bug Fixed

- 解决4.0.6.6引入的共享的屏幕音频未区分导致和用户音频状态冲突的问题
- 解决4.0.6.7引入的修改音频状态异常导致后加入用户看到房间内已发布音频且静音此时音频为发布状态的问题

## Version 4.0.6.8

Feature

- 支持强弱网抗丢包
- 桌面共享设置带宽时通知服务器，可实现1080P视频码流达到10M
- websocket支持数据AES256加密，同时兼容服务器不加密的版本

## Version 4.0.6.7

Improvement

- 屏幕音频共享逻辑调整，不需要接口传参，默认都打开屏幕音频约束

Bug Fixed

- 修复Chrome91及以下版本共享屏幕音频没有开关的问题
- 后加入的用户收到房间内已发布音频状态但显示是未发布的状态的异常修复

## Version 4.0.6.6

Feature

- 屏幕共享新增支持屏幕音频的共享
- 屏幕共享支持设置分辨率、帧率

Improvement

- electron屏幕共享发布接口（electronPublish、publishHandle）添加屏幕音频设置选项

## Version 4.0.6.5

Feature

- 收到服务器下发视频等级时除调整码率外增加对视频分辨率的调整

Improvement

- 白板渲染改为等比例并自适应外部容器
- 白板批注的背景图和背景色功能逻辑在SDK中实现，应用层无需自行设置
- 白板下载支持带背景图下载

Bug Fixed

- 修复微信浏览器内分辨率和帧率不显示的问题

## Version 4.0.6.4

Improvement

- 部分机型(华为mate60,p40,p30等)H5打开后置摄像头，打开的是放大的长焦视频。打开后置摄像头做兼容处理。

## Version 4.0.6.3

Improvement

- 手机H5打开后置摄像头，部分机型(华为mate60,p40,p30等)打开的是放大的长焦视频。打开后置摄像头做兼容处理。

## Version 4.0.6.2

Feature

- 视频设置带宽时通知服务器，可实现1080P视频码流达到10M
- 新增接口video.applyConstraintsWH(w,h),用于视频打开时，分辨率即时更新生效，且通知给服务器

Improvement

- 去掉加入会议时userId带下划线的限制

## Version 4.0.6.1

Feature

- Android Chrome、Android微信内浏览器因支持H264编码但不支持H264解码，此情况下将默认编码设置为VP8，主动设置视频编码为H264时抛错并提醒
- 加会时支持websocket进行多次的重连。重连/重新加会逻辑重构
- 支持集群环境下媒体服务器的切换功能

## Version 4.0.6.0

Feature

- error 提示转化成英文
- 白板图片支持撤销、重做

Bug Fixed

- 修复创建带背景图背景色的白板时自动设置背景图。
- 修复MCU重启后，自动打开重新加会前已发布的音视频后，再手动关闭音视频，此时摄像头指示灯还是开启状态的问题

## Version 4.0.5.7

Improvement

- 屏幕共享去掉指定当前标签页（preferCurrentTab）的约束，改为默认让用户选择整个屏幕
- avdEngine内添加默认设备变动监听从构造函数移到initDeviceHandler内，防止在不支持的浏览器中new AvdEngine报错走不下去

Bug Fixed

- 修复服务器重启后，收到自己白板add和share信令导致白板异常问题

## Version 4.0.5.6

Bug Fixed

- 修复移动端H5打开前后置摄像头时没有设置相应的分辨率、帧率等
- 修复禁音/取消禁音偶现失效的bug
- 修复重连异常问题

## Version 4.0.5.5

Feature

- 支持同时加入多个房间
  - 应用层如用到日志下载bugout, 应用层调用时需要通过var avdEngine = new AVDEngine()实例化后的avdEngine.bugout来访问

Improvement

- 因safari 15.1.X使用H264 编码时会导致页面崩溃, sdk 默认视频编码当遇到是safari 15.1.X时自动设置成VP8,setVideoCoding()接口设置成h264会抛错提示

## Version 4.0.5.3

Feature

- 设备热插拔变化的捕获
- chrome112版本开始，webrtc中状态统计的属性变动做兼容处理
- 新增单独获取桌面共享流的接口: screen.getDisplayMedia().then(function(stream){});
- 桌面共享发布接口screen.publish(displayMediaStream)新增参数displayMediaStream, displayMediaStream指待发布的桌面共享流，可以为空。当空时，会弹出桌面共享选择应用框选择共享的内容。

Bug Fixed

- 修复在ios app中webview，名为Mobile的浏览器中接口等都支持但检测结果为不通过的问题
- mqtt登录报错的问题修复

## Version 4.0.5.2

Bug Fixed

- 修复重新加会后原应用层设置的视频相关参数信息(分辨率宽高、分辨率设置类型、帧率、分辨率宽高比、流名称)失效的问题

## Version 4.0.5.1

Feature

- 视频默认编码由VP8 改为 H264

Bug Fixed

- 修复MQTT邀请同意后回调中方法参数出错的处理

## Version 4.0.5.0

- 修复chrome73、74等低版本中，视频流状态信息回调中分辨率、帧率获取不到的问题

## Version 4.0.4.9

Bug Fixed

- 修复部分Adnroid手机（oppo realmeX2 Android11 微信8.0.31 ，红米K30i Android10 微信8.0.11 等）切换前后置摄像头无效，原因这些手机型号不支持webertc1.0规范中打开前后置的参数的设置，如video:{ 'facingMode': "user” }需要改成video:{ facingMode: {exact: "user"}}。
- 修复订阅ios h5的视频后，ios h5端因网络不好重新加会后又发布时本端不会触发订阅的问题

## Version 4.0.4.8

Feature

- room对象上新增接口joinEfficient(serverURI, accessToken, userId, userName, userData, password),用于合并avdEngine.init()和room.join()的功能,减少异步调用的次数

## Version 4.0.4.7

Feature

- 音频默认编码由PCMU 改为 opus

## Version 4.0.4.6

Feature

- 发布/取消发布、订阅/取消订阅等接口操作操作时，给应用层返回错误信息

Improvement

- 视频取消发布改变状态的回调放到成功后

## Version 4.0.4.5

Feature

- 白板新增：
  - 上传图片 - 支持上传图片在白板上，能上传多个图片，且能自由拖拽，支持图片的选中、旋转、放大、缩小、删除功能
  - 画板放大/缩小 - 支持画板放大/缩小
  - 文字输入-支持添加自由文本框

Bug Fixed

- 解决4.0.4.2版本引入的关闭/退出会议后，原打开的设备不能正常关闭的bug

## Version 4.0.4.2

Feature

- 设备新增订阅接口/取消发布接口/订阅接口/取消订阅接口实现异步完成的回调，需要服务器同步支持，具体接口可以异步处理：
  - video.unpublish().then(function(){}).otherwise(function(e){});
  - video.subscrible().then(function(){}).otherwise(function(e){});
  - video.unsubscrible().then(function(){}).otherwise(function(e){});
  - audio.unpublish().then(function(){}).otherwise(function(e){});
  - audio.subscrible().then(function(){}).otherwise(function(e){});
  - audio.unsubscrible().then(function(){}).otherwise(function(e){});
  - screen.unpublish().then(function(){}).otherwise(function(e){});
  - screen.subscrible().then(function(){}).otherwise(function(e){});
  - screen.unsubscrible().then(function(){}).otherwise(function(e){});
  - room.selfuser.closeMobileFrontVideo().then(function(){}).otherwise(function(e){});
  - room.selfuser.closeMobileBackVideo().then(function(){}).otherwise(function(e){});

Improvement

- avdEngine.obtainRoom(roomId)接口,对参数做了类型验证，不通过会抛错
- room.join(userId,userName,userData,password)接口,对参数userId做了类型验证，不通过会抛错

Bug Fixed

- vivo/华为手机等微信内置浏览器中，指定选择设备打开显示都是前置的问题

## Version 4.0.4.0

Feature

- 新增媒体流推送保活功能
  - 新增媒体流推送失败通知：
    - room.addCallback(RoomCallback.stream_keep_alive_timeout_notify, onStreamKeepAliveTimeoutNotify);
  - 新增设置媒体流推送的保活时长(单位为毫秒),不设置默认为15000毫秒
    - advEngine.setDefaultMediaPublishKeepAliveTime(keepAliveTime);
  - 新增设置当前流推送的保活时长(单位为毫秒)
    - video.setPublishKeepAliveTime(keepAliveTime);
    - audio.setPublishKeepAliveTime(keepAliveTime);
    - screen.setPublishKeepAliveTime(keepAliveTime);

Bug Fixed

- 微信内置浏览器偶现打开设备2011的报错

## Version 4.0.3.9

Feature

- 重新加会时，原应用层设置的视频/桌面共享流名称依然有效，不需要应用层再次设置.

Bug Fixed

- 修复v4.0.3.7引入的日志重复显示的bug

## Version 4.0.3.8

Feature

- chrome96开始，桌面共享的选择框新增当前操作页的chrome tab，即参数preferCurrentTab = true

Bug Fixed

- Chrome103报错问题修复

## Version 4.0.3.7

Improvement

- SDK日志级别默认值由error改为info

Bug Fixed

- 浏览器检测接口中关于桌面共享的支持能力修复

## Version 4.0.3.6

Feature

- 新增关于restful接口返回值的日志

Improvement

- Android Firefox不支持VP8, 如应用层设置的是VP8, SDK自动调整成H264

## Version 4.0.3.5

Bug Fixed

- 如用户麦克风已经打开但静音，断网重连加会成功后会打开用户的麦克风

## Version 4.0.3.4

Improvement

- 白板中撤销批注操作逻辑优化

Bug Fixed

- 当A、B用户都在房间时，B用户网络不好重新加会，这时A收到812后离开房间，等B用户重新加会成功后room.getParticipants()中还能查到A用户信息

## Version 4.0.3.3

Feature

- firefox禁用多流

## Version 4.0.2.8

Feature

- 支持firefox：
  - 网络状态相关：
    - 房间级别中不提供数据包、数据包丢包数、丢包率
    - 视频状态不提供所有状态，因为没有提供trackId,resolution,frameRate
    - 音频状态不提供所有状态，因为没有提供trackId
  - 支持视频多流
  - 支持桌面共享
  - safari支持视频多流

Improvement

- 因firefox浏览器、硬件设备不支持音频isac编码，默认由isac_16k改成pcmu

Bug Fixed

- 本端打开多个摄像头时，更改发布视频源端的视频质量的逻辑修复bug

## Version 4.0.2.4

Improvement

- 公聊私聊使用服务器时间戳

## Version 4.0.2.3

Feature

- 新增加密算法接口，支持AES128/AES256/国密等加密方案的设置,avdEngine.setDataCryptoType(DataCryptoType.AES256)
- 支持safari中显示每路视频的分辨率、帧率、数据包数等

Bug Fixed

- 会议中看android手机的码流显示等正常。 android手机断网3分钟以上重新加会后, 码流等都不显示bug
- 当会议里有多人打开视频时，本地断网重新加会后，再打开视频会报错bug

## Version 4.0.2.2

Feature

- 网络状态处理,chrome86以前的版本，查看远端视频的分辨率及帧率

Bug Fixed

- 解决mac chrome中视频会卡死几秒，花屏，绿屏的情况
- 解决音频PCMA报错的问题
- 解决音频批量订阅时，会存在只重复订阅同一个用户音频的bug

## Version 4.0.2.1

Feature

- 多流场景下，视频的网络状态只返回当前使用流的状态
- 多流场景下，每一路流分配相应的码流

Improvement

- BrowserDetect中原sdk支持的chrome的最低版本从72改成73

Bug Fixed

- 多流场景下，本地打开视频>再打开桌面共享>本地关闭视频>本地打开视频，远端用户会看不到共享
- 网络状态处理,关于视频的分辨率、帧率在 < chrome86版本之前不显示的处理

## Version 4.0.2.1

Feature

- 多流场景下，视频的网络状态只返回当前使用流的状态
- 多流场景下，每一路流分配相应的码流

Improvement

- BrowserDetect中原sdk支持的chrome的最低版本从72改成73

Bug Fixed

- 多流场景下，本地打开视频>再打开桌面共享>本地关闭视频>本地打开视频，远端用户会看不到共享
- 网络状态处理,关于视频的分辨率、帧率在 < chrome86版本之前不显示的处理

## Version 4.0.2.0

Feature

- 网络状态处理，返回了包括房间丢包率、媒体的丢包数等在内的参数,具体见room.addCallback(RoomCallback.connection_indicator, onConnectionIndicator);
- 音频自动订阅时,支持开启对多路音频进行批量订阅处理

Bug Fixed

- 多流时打开本地音频报错

## Version 4.0.1.9

Feature

- 分辨率设置类型默认值从强制即ResolutionSetType.exact改为期望即ResolutionSetType.ideal
- 视频带宽相关对外接口调整：
  - avdEngine.setDefaultVideoParams(width,height,resolutionSetType,frameRate,maxBandwidth)改为avdEngine.setDefaultVideoParams(width,height,resolutionSetType,frameRate)
  - avdEngine.setDefaultScreenParams(maxWidth,maxHeight,minFrameRate,maxFrameRate,maxBandwidth)改为avdEngine.setDefaultScreenParams(maxWidth,maxHeight,minFrameRate,maxFrameRate)
- 非多流时，支持接受服务器下发的资源调整指令，进行视频源端的码率低等级调整
- 下载的日志中，每条日志的时间戳带当前毫秒数

Improvement

- 修改视频/桌面共享带宽方法，原只能在视频/桌面共享发布后调用才生效，现优化为视频/桌面共享发布前调用该接口就可以设置，然后视频/桌面共享发布就会生效

Bug Fixed

- 白板description属性设置异常的问题
- 5g热点切换成公司wifi后，本端打开的视频及音频再操作失败问题

## Version 4.0.1.8

Bug Fixed

- 修复了A,B二端都打开视频的情况下，A端关闭视频后，订阅到的B端视频卡死的bug

## Version 4.0.1.7

Feature

- 支持音频流分离。将桌面共享的音频和用户的音频分离成两个不同的stream, 以解决ios safari等不能同时听到二类声音的问题。

Improvement

- 白板橡皮擦逻辑针对对号、错号、固定箭头判断区域做了增大处理
- 修改视频带宽方法，原只能在视频发布后调用才生效，现优化为视频发布前调用该接口就可以设置，然后视频发布就会生效

Bug Fixed

- 网络不好重新加会成功后，原共享的白板及相关批注等逻辑优化
  - 切换到鼠标状态原画笔还存在
  - 橡皮擦不能连续擦除
  - 关闭白板再重新打开，不能恢复之前没被擦掉的批注
  - 断线重连后，关闭再打开白板，之前的批注擦不掉

## Version 4.0.1.6

Feature

- 支持多流

## Version 4.0.1.5

Feature

- 设备检测时麦克风音量的检测回调接口：
  - avdEngine.checkAudioLevel(1000,function showAudioLevel(audioLevel) {});
- 支持网络状态，如房间中总的上下行码流，各个音视频的码流等统计。返回的参数是微调，现存在问题：
  - 没有丢包率的计算，原因是没有相关的参数
- 支持ios微信浏览器，要求ios为14.3+
- 支持ios上百度浏览器、极速浏览器、360度全新打造的平板浏览器（设置>视频设置>网页播放开启)、搜狗浏览器、QQ浏览器、firefox浏览器

## Version 4.0.1.4

Improvement

- 关闭房间回调及踢人回调等逻辑优化

Bug Fixed

- 修复了A,B二端都打开视频的情况下，A端关闭再打开视频后，B端订阅成功但视频不显示的bug

## Version 4.0.1.3

Feature

- 针对移动端H5打开前后置摄像头，提供4个接口：
  - user.openMobileFrontVideo
  - user.closeMobileFrontVideo
  - user.openMobileBackVideo
  - user.closeMobileBackVideo
- user对象新增二个接口：
  - user.remotecmdMuteMicrophone(userId)
  - user.remotecmdUnmuteMicrophone(userId)
- 房间room新增回调接口：
  - room.addCallback(RoomCallback.mediaplay_progress_notify, onMediaPlayProgressNotify)

## Version 4.0.1.2

Bug Fixed

- 解决在相同浏览器相同域名访问情况下摄像头/麦克风等设备ID不会改变的问题

## Version 4.0.1.1

Feature

- 白板批注相关日志精简
- 白板更新新增接口:
  - user.updateBoard(board);
  - user.addCallback(UserCallback.board_update_result, function onBoardUpateResult(boardId,backgroundColor,backgroundImage) {})
- 白板下载更新,处理了背景图，背景色的连带保存。annotation.download(backgroundCanvas)

Improvement

- 解除userId不能带_的限制:
  - 取消接口room.composePDUDeviceId(prefix, deviceId),room.splitPDUDeviceId(PDUDeviceId),room.splitUserId(PDUDeviceId)
  - 更改接口user.remotecmdUnpublishCamera(cameraId) 为 user.remotecmdUnpublishCamera(userId,cameraId)

Bug Fixed

- 引用的第三包axios进行实列化成sdkAxios，以区别应用层客户自己的axios包引发冲突

## Version 4.0.1.0

Feature

- 基线于v3.6.0.6
- 与3.X SDK 音视频互通
- 支持移动端H5
- 新增MediaPlayEventNotify,实现媒体播放相关回调mediaplay_started_notify,mediaplay_stoped_notify
- 新增screen.setBandwidth(maxBandwidth)

Improvement

- 接口有变化：
  - avdEngine.setDefaultVideoParams(width,height,resolutionSetType,frameRate,minBandwidth,maxBandwidth) 改成avdEngine.setDefaultVideoParams(width,height,resolutionSetType,frameRate,maxBandwidth)
  - avdEngine.setDefaultScreenParams(maxWidth,maxHeight,minFrameRate,maxFrameRate) 改成 avdEngine.setDefaultScreenParams(maxWidth,maxHeight,minFrameRate,maxFrameRate,maxBandwidth)
  - video.setBandwidth(minBandwidth,maxBandwidth) 改成 video.setBandwidth(maxBandwidth)