简介

声网直播uniapp原生插件是由赣州智悦科技有限公司编写的一款在uniapp中接入声网视频互动直播的原生插件,使用此插件可以完美地对接视频互动直播,合图推流到CDN并播放视频,实时消息发送与接收功能。

目前仅支持Android版,iOS版在计划中。

有任何使用问题,请入QQ群:320125035

其他项目文档

zywork-app-pro快速开发套件文档:https://easydoc.xyz/s/37090916
Svga动画播放uniapp原生插件文档:https://easydoc.xyz/s/63143579

三大组件

1、AgoraView,对应于RtcEngine实例
视频互动直播组件:完成视频录制,视频转码,视频推拉流等功能。

2、AgoraMediaPlayer,对应于AgoraMediaPlayerKit实例
媒体播放器组件:完成对合流后视频的播放功能。

3、AgoraRtm,对应于RtmClient实例
实时消息组件:私人消息与频道消息,支持文本,图片和文件。

注意

1、所有组件的接口与声网官方的接口名称及参数名称保持一致,参数多使用JSON格式。
2、所有组件的接口方法调用返回JSON格式的结果,该结果基本与声网官方的返回结果保持一致(有用的结果)。
3、所有事件函数都以on开头,在组件中使用@onXXX="onXXX"的形式进行事件回调监听。
如创建RtcEngine实例的create方法,在插件中的调用形式为:

agoraView.create({appid: 'appid'}, res => {console.log(res)})

如监听joinChannelSuccess事件,在插件中的使用形式为:

<AgoraView @onJoinChannelSuccess="onJoinChannelSuccess"></AgoraView>

AgoraView直播组件

使用方法

1、在uniapp插件市场中直接下载插件后解压
2、把解压后的zywork-agora目录拷贝到uniapp项目的nativeplugins目录中
3、打开项目的manifest.json文件,在App原生插件中选择本地插件,勾选zywork声网直播插件
4、在nvue页面中直接使用组件
主播:

<AgoraView ref="agoraView1" :style="`position: absolute; left: ${(screenWidth - hostWidth) / 2}px; top: 0px;width: ${hostWidth}px; height: ${hostHeight}px;`" @onJoinChannelSuccess="onJoinChannelSuccess" @onLeaveChannel="onLeaveChannel" @onRemoteVideoStateChanged="onRemoteVideoStateChanged" @onUserJoined="onUserJoined" @onUserOffline="onUserOffline"></AgoraView>

上麦嘉宾:

<AgoraView ref="agoraView2" :style="`position: absolute; left: 0px; top: ${hostHeight + 2}px; width: ${guestWidth}px; height: ${guestHeight}px;`" @onJoinChannelSuccess="onJoinChannelSuccess" @onLeaveChannel="onLeaveChannel" @onRemoteVideoStateChanged="onRemoteVideoStateChanged"></AgoraView>

5、相关接口调用示例

/** * 主播开启直播间 */ export const openLive = (self) => { self.isHost1 = true let agoraView = self.$refs.agoraView1 agoraView.create({appid: AGORA_APPID}) if (self.houseType.onlyAudio) { // 如果只要语音,则关闭视频模块 agoraView.disableVideo(res => {}) } else { agoraView.enableVideo(res => {}) } agoraView.setEnableSpeakerphone({enableSpeaker: true}, res => {}) if (self.houseType.onlyAudio) { // 声音检测 agoraView.enableAudioVolumeIndication({interval: 300, smooth: 3, reportVad: true}) } agoraView.setVideoEncoderConfiguration({width: self.houseType.width, height: self.houseType.height}, res => {}) agoraView.setClientRole(1, res => {}) if (!self.houseType.onlyAudio) { // 是否启用视频 agoraView.setupLocalVideo({channelName: self.liveChannelId, uid: self.hostInfo.userId}, res => {}) agoraView.setBeautyEffectOptions({ enabled: true, contrastLevel: CONTRAST_LEVEL, lightening: LIGHTENING, smoothness: SMOOTHNESS, redness: REDNESS }) agoraView.startPreview(res => {}) } // 获取rtc token后加入直播频道 doGet('/agora-token/rtc/' + self.liveChannelId + '/' + self.hostInfo.userId, {}, {}, true).then(response => { let [err, res] = response if (res.data.code === ResponseStatus.OK) { agoraView.joinChannel({ token: res.data.data, channelName: self.liveChannelId, uid: self.hostInfo.userId, }, res => {}) } }).catch(error => { }) }

6、所有接口都可以参考声网官方的API文档Agora Android V3.1.2

注意事项

1、在同一个nvue页面中可以使用多个AgoraView组件,每一个AgoraView表示一个主播(上麦嘉宾)端,如直播5人间,则有5个AgoraView组件。
2、每个AgoraView都需要指定不同的ref属性;
3、每个AgoraView都使用absolutefixed定位方式,具体的定位值,宽高等可自定义;
4、在开启房间的主播端需要监听更多的事件,而在上麦嘉宾端有些事件并不需要监听;
5、在AgoraView组件中,不要使用v-if的方式来动态渲染组件,可以使用图片遮盖或动态修改定位值的方式来显示与隐藏AgoraView组件;
6、AgoraView的宽高比需要与视频采集分享率的宽高比一致(后面会有详细说明)。

接口说明

create,创建RtcEngine实例

create({ appid: AGORA_APPID }, res => {})

返回结果:

{ code: 0 | 1, message: 'RtcEngine create成功' | 'RtcEngine create失败' }

enableVideo,开启视频模块

enableVideo(res => {})

返回结果:

{ code: 0 | 负数, message: 'enableVideo成功' | 'enableVideo失败' }

disableVideo,关闭视频模块

disableVideo(res => {})

返回结果:

{ code: 0 | 负数, message: 'disableVideo成功' | 'disableVideo失败' }

enableAudio,开启音频模块

enableAudio(res => {})

返回结果:

{ code: 0 | 负数, message: 'enableAudio成功' | 'enableAudio失败' }

disableAudio,关闭音频模块

disableAudio(res => {})

返回结果:

{ code: 0 | 负数, message: 'disableAudio成功' | 'disableAudio失败' }

setEnableSpeakerphone,设置是否启用扬声器

setEnableSpeakerphone({ enableSpeaker: true | false // 是否启用扬声器 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'setEnableSpeakerphone成功' | 'setEnableSpeakerphone失败' }

setVideoEncoderConfiguration,设置视频编码配置,主要设置视频采集分辨率的宽高

setVideoEncoderConfiguration({ width: 360, // 视频采集分辨率的宽 height: 640 // 视频采集分辨率的高 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'setVideoEncoderConfiguration成功' | 'setVideoEncoderConfiguration失败' }

注意:视频采集分辨率的宽高比与单个直播视频窗口的宽高比要保持一致,否则会出现视频拉伸的情况。

setClientRole,设置加入频道的用户类型

setClientRole(1 | 2, res => {}) // 1表示主播,2表示观众

返回结果:

{ code: 0 | 负数, message: 'setClientRole成功' | 'setClientRole失败' }

setupLocalVideo,设置本地视频

setupLocalVideo({ channelName: 'demoChannel1', // 频道名称 uid: 1001 // 用户编号,int型 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'setupLocalVideo成功' | 'setupLocalVideo失败' }

setLocalRenderMode,设置本地视频渲染模式

setLocalRenderMode({ renderMode: 2, // 本地视图渲染模式 mirrorMode: 0 // 本地视图的镜像模式 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'setLocalRenderMode成功' | 'setLocalRenderMode失败' }

注意:详细参数说明请参考声网官方API文档setLocalRenderMode

setupRemoteVideo,设置远端视频

setupRemoteVideo({ channelName: 'demoChannel1', // 频道名称 uid: 1001 // 用户编号,int型 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'setupRemoteVideo成功' | 'setupRemoteVideo失败' }

setRemoteRenderMode,设置远端视频渲染模式

setRemoteRenderMode({ renderMode: 2, // 远端用户视图渲染模式 mirrorMode: 0 // 远端用户视图的镜像模式 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'setRemoteRenderMode成功' | 'setRemoteRenderMode失败' }

注意:详细参数说明请参考声网官方API文档setRemoteRenderMode

startPreview,开始视频预览

startPreview(res => {})

返回结果:

{ code: 0 | 负数, message: 'startPreview成功' | 'startPreview失败' }

stopPreview,停止视频预览

stopPreview(res => {})

返回结果:

{ code: 0 | 负数, message: 'stopPreview成功' | 'stopPreview失败' }

setBeautyEffectOptions,设置是否启用美颜和美颜参数

setBeautyEffectOptions({ enabled: true | false, // 是否启用美颜功能 contrastLevel: 1, // 亮度明暗对比度 lightening: 0.7, // 亮度,取值范围为 [0.0, 1.0],其中 0.0 表示原始亮度,默认值为 0.7。可用来实现美白等视觉效果 smoothness: 0.5, // 平滑度,取值范围为 [0.0, 1.0],其中 0.0 表示原始平滑等级,默认值为 0.5。可用来实现祛痘、磨皮等视觉效果 redness: 0.1 // 红色度,取值范围为 [0.0, 1.0],其中 0.0 表示原始红色度,默认值为 0.1。可用来实现红润肤色等视觉效果 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'setBeautyEffectOptions成功' | 'setBeautyEffectOptions失败' }

joinChannel,加入直播频道

setBeautyEffectOptions({ token: 'token value', // Agora鉴权token,需要在后台生成并返回 channelName: 'demoChannel1', // 频道名 uid: 1001 // 用户编号,int型 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'joinChannel成功' | 'joinChannel失败' }

joinChannel执行成功将会触发以下回调事件:

1)onJoinChannelSuccess,本地用户成功加入频道回调事件

onJoinChannelSuccess = (e) => { let res = e.detail console.log(res.channelName) // 频道名 console.log(res.uid) // 加入频道的本地用户编号 }

注意:本地用户加入直播频道成功会触发此回调事件

2)onUserJoined,远端用户成功加入频道回调事件

onUserJoined = (e) => { let res = e.detail console.log(res.uid) // 加入频道的远端用户编号 }

注意:远端用户加入直播频道成功,则在麦上的所有主播(嘉宾)都会触发此回调事件。如A和B已经上麦,C加入成功,则A和B都会触发C加入频道的回调事件,C会触发A加入频道的回调事件,C还会触发B加入频道的回调事件。

3)onRemoteVideoStateChanged,远端视频状态改变回调事件

onRemoteVideoStateChanged = (e) => { let res = e.detail console.log(res.uid) // 发生视频状态改变的远端用户 ID console.log(res.state) // 远端视频流状态 console.log(res.reason) // 远端视频流状态改变的具体原因 }

e.detail.state === 1时表示本地用户已接收远端视频首包,此时可以在本地用户端调用setupRemoteVideo显示远端用户视频。

注意:详细的返回结果说明请参考声网官方的API文档onRemoteVideoStateChanged

4)onRemoteAudioStateChanged,远端音频状态改变回调事件

onRemoteAudioStateChanged = (e) => { let res = e.detail console.log(res.uid) // 发生音频状态改变的远端用户 ID console.log(res.state) // 远端音频流状态 console.log(res.reason) // 远端音频流状态改变的具体原因 }

e.detail.state === 1时表示本地用户已接收远端音频首包,但此时由于只需要音频,而不需要视频,则不需要本地用户端调用setupRemoteVideo显示远端用户视频。

注意:详细的返回结果说明请参考声网官方的API文档onRemoteVideoStateChanged

leaveChannel,离开直播频道

leaveChannel(res => {})

返回结果:

{ code: 0 | 负数, message: 'leaveChannel成功' | 'leaveChannel失败' }

leaveChannel执行成功会触发以下回调事件:

1)onLeaveChannel,本地用户离开直播频道回调事件

onLeaveChannel = (e) => { let res = e.detail console.log(res.totalDuration) // 通话时长 console.log(res.users) // 直播频道内的用户数 }

2)onUserOffline,远端用户离开直播频道回调事件

onUserOffline = (e) => { let res = e.detail console.log(res.uid) // 主播ID console.log(res.reason) // 离线原因 }

注意:离线原因请参考声网官方API文档onUserOffline

adjustPlaybackSignalVolume,调节本地播放的所有远端用户音量

adjustPlaybackSignalVolume({ volume: 100 // 播放音量,取值范围为 [0, 400] }, res => {})

返回结果:

{ code: 0 | 负数, message: 'adjustPlaybackSignalVolume成功' | 'adjustPlaybackSignalVolume失败' }

setLiveTranscoding,设置视频合流参数(多个直播视频流合成一个视频流)

setLiveTranscoding({ audioChannels: 2, audioBitrate: 96, width: self.videoWidth, height: self.videoHeight, videoBitrate: 1200, videoFramerate: 30, backgroundImageUrl: PLAYER_BG, backgroundImageX: 0, backgroundImageY: 0, backgroundImageWidth: self.videoWidth, backgroundImageHeight: self.videoHeight, users: [ { uid: self.hostInfo.userId, x: (self.videoWidth - self.videoHostWidth) / 2, y: 0, width: self.videoHostWidth, height: self.videoHostHeight, zOrder: 1, audioChannel: 0 } ...... ] }, res => {})

返回结果:

{ code: 0 | 负数, message: 'setLiveTranscoding成功' | 'setLiveTranscoding失败' }

注意:上面示例代码中的self.引用的数据是在nvue页面的data中定义的数据或根据屏幕大小等计算的值。详情请参考setLiveTranscoding, LiveTranscoding和TranscodingUser

setLiveTranscoding执行成功会触发以下回调事件:
1)onTranscodingUpdated,合图转码更新回调事件

onTranscodingUpdated= (e) => { let res = e.detail console.log(res.update) // true,表示transcoding已更新 }

addPublishStreamUrl,添加视频推流地址

addPublishStreamUrl({ url: 'push_address_url', // 推流地址URL,可以使用腾讯云直播生成推流地址 transcodingEnabled: true // 是否开启直播转码,如果是单个主播,不需要开启直播转码 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'addPublishStreamUrl成功' | 'addPublishStreamUrl失败' }

注意:如果需要推流到多个地址,可多次调用。

removePublishStreamUrl,删除视频推流地址

removePublishStreamUrl({ url: 'push_address_url', // 推流地址URL,请替换成实际的推流地址 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'removePublishStreamUrl成功' | 'removePublishStreamUrl失败' }

注意:如果删除多个推流地址,可多次调用。

enableAudioVolumeIndication,启用说话者音量提示

enableAudioVolumeIndication({ interval: 300, // 指定音量提示的时间间隔 smooth: 3, // 平滑系数,指定音量提示的灵敏度。取值范围为 [0, 10],建议值为 3 reportVad: true // 是否开启人声检测 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'enableAudioVolumeIndication成功' | 'enableAudioVolumeIndication失败' }

后续触发的回调事件:
1)onAudioVolumeIndication,提示频道内谁正在说话及说话者音量的回调事件

onAudioVolumeIndication= (e) => { let res = e.detail console.log(res) // 每个说话者的用户 ID 和音量信息 }

本地用户:

res = { '0': 1, // 本地用户在说话 }

远端用户:

res = { '1001': 0, '1002': 0 }

注意:详情请参考声网官方API文档onAudioVolumeIndication

2)onActiveSpeaker,监测到最活跃用户回调事件

onActiveSpeaker= (e) => { let res = e.detail console.log(res.uid) // 远端最活跃用户的编号 }

renewToken,更新Token

renewToken({ token: 'new rtc token' // 声网鉴权Token,后台动态生成 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'renewToken成功' | 'renewToken失败' }

getConnectionState,获取网络连接状态

getConnectionState(res => {})

返回结果:

{ connectionState: 1 | 2 | 3 | 4 | 5 }

注意:返回结果详情请参考声网官方API文档getConnectionState

startAudioMixing,开始混音

startAudioMixing({ filePath: '/storage/test.mp3', // 指定需要混音的本地或在线音频文件的绝对路径(包含文件名后缀) loopback: false, replace: false, cycle: 1 // 音频文件循环播放的次数 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'startAudioMixing成功' | 'startAudioMixing失败' }

注意:详细参数请参考声网官方API文档startAudioMixing

setDefaultAudioRoutetoSpeakerphone,设置是否默认使用扬声器

setDefaultAudioRoutetoSpeakerphone({ defaultSpeaker: true // 是否默认从扬声器播放音频 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'setDefaultAudioRoutetoSpeakerphone成功' | 'setDefaultAudioRoutetoSpeakerphone失败' }

isSpeakerphoneEnabled,判断扬声器是否启用

isSpeakerphoneEnabled(res => {})

返回结果:

{ code: 0 | -1, message: '扬声器已启用' | '扬声器已禁用' }

startChannelMediaRelay,开始跨频道媒体流转发,可用于跨频道主播PK

startChannelMediaRelay({ srcChannelName: 'demoChannel1', // 源频道名 srcToken: 'rtc token', // 源频道使用的声网鉴权Token destChannelName: 'demoChannel2', // 目标频道 destToken: 'rtc token', // 目标频道使用的声网鉴权Token uid: 1002 // 用户编号 }, res => {})

返回结果:

{ code: 0 | 负数, message: 'startChannelMediaRelay成功' | 'startChannelMediaRelay失败' }

跨频道PK,两个频道的主播都需要调用此接口。

注意:更多详情请参考声网官方API文档startChannelMediaRelay

成功调用后会触发以下回调事件:
1)onChannelMediaRelayStateChanged,跨频道媒体流状态改变回调事件

onChannelMediaRelayStateChanged= (e) => { let res = e.detail console.log(res.code) // 跨频道媒体流转发出错的错误码 console.log(res.state) // 跨频道媒体流转发状态 }

注意:详情请参考声网官方API文档onChannelMediaRelayStateChanged

2)onChannelMediaRelayEvent,跨频道媒体流转发事件

onChannelMediaRelayEvent= (e) => { let res = e.detail console.log(res.code) // 跨频道媒体流转发事件码 }

注意:详情请参考声网官方API文档onChannelMediaRelayEvent

stopChannelMediaRelay,停止跨频道视频直播

stopChannelMediaRelay(res => {})

返回结果:

{ code: 0 | 负数, message: 'stopChannelMediaRelay成功' | 'stopChannelMediaRelay失败' }

destroy,销毁RtcEngine实例

destroy()

其他事件:
onTokenPrivilegeWillExpire,Token即将过期回调事件

onTokenPrivilegeWillExpire= (e) => { let res = e.detail console.log(res.token) // 即将过期的Token值 }

onConnectionStateChanged,连接状态改变回调事件

onConnectionStateChanged= (e) => { let res = e.detail console.log(res.state) // console.log(res.reason) // }

注意:详情请参考声网官方APIonConnectionStateChanged

onConnectionLost,连接丢失回调事件

onConnectionLost= (e) => { let res = e.detail console.log(res.connectionLost) // 是否丢失连接 }

AograMediaPlayer播放器组件

使用方法

1、在uniapp插件市场中直接下载插件后解压
2、把解压后的zywork-agora目录拷贝到uniapp项目的nativeplugins目录中
3、打开项目的manifest.json文件,在App原生插件中选择本地插件,勾选zywork声网直播插件
4、在nvue页面中直接使用组件

注意事项

接口说明

AgoraRtm实时消息组件

使用方法

1、在uniapp插件市场中直接下载插件后解压
2、把解压后的zywork-agora目录拷贝到uniapp项目的nativeplugins目录中
3、打开项目的manifest.json文件,在App原生插件中选择本地插件,勾选zywork声网直播插件
4、在nvue页面中直接使用组件

注意事项

接口说明

SVGA动画播放

SVGA动画播放通常用于礼物的展示,可直接使用赣州智悦科技有限公司编写的SVGA动画播放uniapp插件。
插件地址:https://ext.dcloud.net.cn/plugin?id=2763
文档地址:https://easydoc.xyz/s/63143579

让你意想不到的直播插件相关推荐

  1. batchplot 3.6.2 插件_直播插件体系设计

    | 导语   直播页面是一个功能丰富且复杂的页面,整个页面几乎全部由若干个功能组件构成,在这样一个背景下,如何通过前期的合理设计来接入这些功能组件,同时提高页面的扩展性和可维护性. 一.背景 开播了鹅 ...

  2. OBS插件开发以及OBS插件的选择(obs直播插件)

    obs版本的选择: 工作室版,优化了很多东西,缺点是不能用插件,在部分机型不稳定,因为更新的很频繁.不过这个插件不能用的说法还是停留在早起,截至到今天已经完美支持,所以在不久的将来会越来越好,如果是开 ...

  3. 小葫芦直播管家找不到服务器,小葫芦直播管家-开播版,直播插件手动安装教程...

    小葫芦直播管家-开播版,直播插件手动安装教程 小葫芦直播管家-开播版最新版本支持添加各种直播插件啦!先给大家分享简单快速的添加方法. 注意:准备好32位的OBS Studio插件!可前往 小葫芦插件市 ...

  4. OBS插件开发以及OBS插件的选择(obs直播插件)研究思路

    obs版本的选择: 工作室版,优化了很多东西,缺点是不能用插件,在部分机型不稳定,因为更新的很频繁.不过这个插件不能用的说法还是停留在早起,截至到今天已经完美支持,所以在不久的将来会越来越好,如果是开 ...

  5. PHP写的电视直播插件实例创建流程

    PHP写的电视直播插件实例创建流程 这是最近写的一个PHP电视直播插件实例. 作者:G.FLOWER 主页:https://wdc.store 目录结构: 创建zb目录,可放在网站二级目录 创建zby ...

  6. 插件记录-dplayer直播插件

    "dplayer": "^1.26.0", 直播插件的使用记录,支持m3u8格式的直播或者回放视频播放,ios和安卓兼容性良好,ios不支持自动播放. impo ...

  7. 微信小程序点播插件_小程序直播插件接入 - 微信小程序

    当下直播带货还是挺火的,对于直播项目理解拉流和推流基本就能搞定.之前小程序直播插件未开放的时候,当时是引入第三方直播服务进行做的:当下又有直播需求,这次便把小程序直播插件模块体验了下:小程序直播插件还 ...

  8. 无人直播插件 直播替换安装使用教程

    无人直播插件 直播替换安装使用教程 一.适用机型及系统 1.机型:所有iphone机型,可越狱即可 2.系统:支持13系统及以上所有可越狱系统 二.安装手机端 1.越狱 (1)Windows越狱方法: ...

  9. 网络直播插件大全 v1.2 下载

    Welcome to my blog! <script language="javascript" src="http://avss.b15.cnwg.cn/cou ...

最新文章

  1. 数组作为函数的参数传参时,数组名会退化为指针
  2. IE后退按钮过期原因
  3. 大学基础课程之重要性
  4. 阿里云短信官方的java示例是错误的
  5. ASP.net:命名空间“System.Xml”中不存在类型(是缺少程序集引用吗?)
  6. C#如何判断质数(转)
  7. Hive2.1.1、Hadoop2.7.3 部署
  8. c语言memcmp和java的_C语言memcmp()函数:比较m字节长的两个字符串s1和s2
  9. matlab信号内插,基于VC++和Matlab的数字信号内插处理系统
  10. 测试nb信号的软件_NB频点概述
  11. STM8S103之外部中断
  12. 浏览班级为计算机的同学记录的命令,2011年全国计算机等级考试二级VFP笔记(4)...
  13. 阿里云MaxComputer SQL学习之内置函数
  14. 美国十大毕业典礼演讲:记着你总会死去……
  15. Vue3中使用生命周期函数
  16. ecshop 模板支持php,ecshop模板文件不支持php语句解决办法
  17. 计算机一级常用英语缩写,电脑常用英文单词和缩写
  18. Kafka SASL 安全认证
  19. wordpress 数据库_如何在WordPress中创建视频库(逐步)
  20. 在OpenCV里使用背景去除

热门文章

  1. iOS那些好用的开发工具
  2. 计算机信息安全专业就业情况,2021高考全国2卷英语试题及答案【word精校版】
  3. linux卸载内核命令,ubuntu内核升级及卸载
  4. 入职第二天的工作总结
  5. RTOS内功修炼记(三)—— 内核到底是如何管理中断的?
  6. android蓝牙传输脉冲,一种基于Android操作系统的激光测距仪蓝牙通信方法与流程...
  7. 弘辽科技:如何抢占平台流量?提升人货匹配效率
  8. C语言课设设备管理系统(大作业)
  9. 算法笔记- K均值(K-Means)
  10. 5G、折叠屏之外,努比亚α的新探索