鸿蒙HarmonyOS——AVSession开发指导

AVSession开发指导

说明:

AVSession的所有接口均为系统接口,其功能仅提供给系统应用使用。

会话接入端开发指导

基本概念

  • 会话元数据'AVMetadata': 媒体数据相关属性,包含标识当前媒体的ID(assetId),上一首媒体的ID(previousAssetId),下一首媒体的ID(nextAssetId),标题(title),专辑作者(author),专辑名称(album),词作者(writer),媒体时长(duration)等属性。
  • 会话描述符'AVSessionDescriptor': 描述媒体会话的相关信息。包含标识会话的ID(sessionId),会话的类型type(音频Audio/视频Video),会话自定义名称(sessionTag),会话所属应用的信息(elementName)等。
  • 媒体播放状态'AVPlaybackState':用于描述媒体播放状态的相关属性。包含当前媒体的播放状态(state)、位置(position)、速度(speed)、缓冲时间(bufferedTime)、循环模式(loopMode)、是否收藏(isFavorite)等属性。

接口说明

会话接入端常用接口如下表所示。接口返回值有两种返回形式:callback和promise,下表中为callback形式接口,promise和callback只是返回值方式不一样,功能相同。更多API说明请参见API文档。

表1:会话接入端常用接口

接口名描述
createAVSession(context: Context, tag: string, type: AVSessionType, callback: AsyncCallback): void创建会话
setAVMetadata(data: AVMetadata, callback: AsyncCallback): void设置会话元数据
setAVPlaybackState(state: AVPlaybackState, callback: AsyncCallback): void设置会话播放状态信息
setLaunchAbility(ability: WantAgent, callback: AsyncCallback): void设置启动ability
getController(callback: AsyncCallback): void获取当前会话自身控制器
getOutputDevice(callback: AsyncCallback): void获取音频输出设备信息
activate(callback: AsyncCallback): void激活会话
destroy(callback: AsyncCallback): void销毁会话

开发步骤

1.导入模块接口

import avSession from '@ohos.multimedia.avsession';
import wantAgent from '@ohos.app.ability.wantAgent';
import featureAbility from '@ohos.ability.featureAbility';

2.创建会话并激活会话

// 全局变量定义
let mediaFavorite = false;
let currentSession = null;
let context = featureAbility.getContext();// 创建音频类型会话
avSession.createAVSession(context, "AudioAppSample", 'audio').then((session) => {currentSession = session;currentSession.activate();  // 激活会话
}).catch((err) => {console.info(`createAVSession : ERROR : ${err.message}`);
});

3.设置AVSession会话信息,包括: - 设置会话元数据,除了媒体ID必选外,可选设置媒体标题、专辑信息、媒体作者、媒体时长、上一首/下一首媒体ID等。详细的会话元数据信息可参考API文档中的AVMetadata。 - 设置启动Ability,通过WantAgent的接口实现。WantAgent一般用于封装行为意图信息。 - 设置播放状态。

// 设置会话元数据
let metadata  = {assetId: "121278",title: "lose yourself",artist: "Eminem",author: "ST",album: "Slim shady",writer: "ST",composer: "ST",duration: 2222,mediaImage: "https://www.example.com/example.jpg",       // 请开发者根据实际情况使用subtitle: "8 Mile",description: "Rap",lyric: "https://www.example.com/example.lrc",            // 请开发者根据实际情况使用previousAssetId: "121277",nextAssetId: "121279",
};
currentSession.setAVMetadata(metadata).then(() => {console.info('setAVMetadata successfully');
}).catch((err) => {console.info(`setAVMetadata : ERROR : ${err.message}`);
});
// 设置启动ability
let wantAgentInfo = {wants: [{bundleName: "com.neu.setResultOnAbilityResultTest1",abilityName: "com.example.test.EntryAbility",}],operationType: wantAgent.OperationType.START_ABILITIES,requestCode: 0,wantAgentFlags:[wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]
}wantAgent.getWantAgent(wantAgentInfo).then((agent) => {currentSession.setLaunchAbility(agent).then(() => {console.info('setLaunchAbility successfully');}).catch((err) => {console.info(`setLaunchAbility : ERROR : ${err.message}`);});
});
// 设置播放状态
let PlaybackState = {state: avSession.PlaybackState.PLAYBACK_STATE_STOP,speed: 1.0,position:{elapsedTime: 0, updateTime: (new Date()).getTime()},bufferedTime: 1000,loopMode: avSession.LoopMode.LOOP_MODE_SEQUENCE,isFavorite: false,
};
currentSession.setAVPlaybackState(PlaybackState).then(() => {console.info('setAVPlaybackState successfully');
}).catch((err) => {console.info(`setAVPlaybackState : ERROR : ${err.message}`);
});
// 获取当前session会话对象自身的控制器
currentSession.getController().then((selfController) => {console.info('getController successfully');
}).catch((err) => {console.info(`getController : ERROR : ${err.message}`);
});
// 获取音频输出设备信息
currentSession.getOutputDevice().then((outputInfo) => {console.info(`getOutputDevice successfully, deviceName : ${outputInfo.deviceName}`);
}).catch((err) => {console.info(`getOutputDevice : ERROR : ${err.message}`);
});

4.注册控制命令监听

// 注册播放命令监听
currentSession.on('play', () => {console.log("调用AudioPlayer.play方法");// 设置播放状态currentSession.setAVPlaybackState({state: avSession.PlaybackState.PLAYBACK_STATE_PLAY}).then(() => {console.info('setAVPlaybackState successfully');}).catch((err) => {console.info(`setAVPlaybackState : ERROR : ${err.message}`);});
});// 注册暂停命令监听
currentSession.on('pause', () => {console.log("调用AudioPlayer.pause方法");// 设置播放状态currentSession.setAVPlaybackState({state: avSession.PlaybackState.PLAYBACK_STATE_PAUSE}).then(() => {console.info('setAVPlaybackState successfully');}).catch((err) => {console.info(`setAVPlaybackState : ERROR : ${err.message}`);});
});// 注册停止命令监听
currentSession.on('stop', () => {console.log("调用AudioPlayer.stop方法");// 设置播放状态currentSession.setAVPlaybackState({state: avSession.PlaybackState.PLAYBACK_STATE_STOP}).then(() => {console.info('setAVPlaybackState successfully');}).catch((err) => {console.info(`setAVPlaybackState : ERROR : ${err.message}`);});
});// 注册下一首命令监听
currentSession.on('playNext', () => {// 如果媒体文件未准备好,则下载并缓存媒体文件,设置准备状态currentSession.setAVPlaybackState({state: avSession.PlaybackState.PLAYBACK_STATE_PREPARE}).then(() => {console.info('setAVPlaybackState successfully');}).catch((err) => {console.info(`setAVPlaybackState : ERROR : ${err.message}`);});// 成功获取媒体文件currentSession.setAVMetadata({assetId: '58970105', title: '不如我们明天见'}).then(() => {console.info('setAVMetadata successfully');}).catch((err) => {console.info(`setAVMetadata : ERROR : ${err.message}`);});console.log("调用AudioPlayer.play方法");// 设置播放状态let time = (new Date()).getTime();currentSession.setAVPlaybackState({state: avSession.PlaybackState.PLAYBACK_STATE_PLAY, position: {elapsedTime: 0, updateTime: time}, bufferedTime:2000}).then(() => {console.info('setAVPlaybackState successfully');}).catch((err) => {console.info(`setAVPlaybackState : ERROR : ${err.message}`);});
});// 注册播放快进命令监听
currentSession.on('fastForward', () => {console.log("调用AudioPlayer的倍速播放");// 设置播放状态currentSession.setAVPlaybackState({speed: 2.0}).then(() => {console.info('setAVPlaybackState successfully');}).catch((err) => {console.info(`setAVPlaybackState : ERROR : ${err.message}`);});
});// 注册跳播命令监听
currentSession.on('seek', (time) => {console.log("调用AudioPlayer的seek方法");// 设置播放状态currentSession.setAVPlaybackState({position: {elapsedTime: time, updateTime: (new Data()).getTime()}}).then(() => {console.info('setAVPlaybackState successfully');}).catch((err) => {console.info(`setAVPlaybackState : ERROR : ${err.message}`);});
});// 注册设置播放速度命令监听
currentSession.on('setSpeed', (speed) => {console.log(`调用AudioPlayer的倍速播放 ${speed}`);// 设置播放状态currentSession.setAVPlaybackState({speed: speed}).then(() => {console.info('setAVPlaybackState successfully');}).catch((err) => {console.info(`setAVPlaybackState : ERROR : ${err.message}`);});
});// 注册设置播放循环模式命令监听
currentSession.on('setLoopMode', (mode) => {console.log(`应用自身切换循环模式 ${mode}`);// 设置播放状态currentSession.setAVPlaybackState({loopMode: mode}).then(() => {console.info('setAVPlaybackState successfully');}).catch((err) => {console.info(`setAVPlaybackState : ERROR : ${err.message}`);});
});// 注册设置歌曲收藏命令监听
currentSession.on('toggleFavorite', (assetId) => {console.log(`应用保存当前assetId为喜爱 ${assetId}`);// 根据上一次的状态进行切换let favorite = mediaFavorite == false ? true : false;currentSession.setAVPlaybackState({isFavorite: favorite}).then(() => {console.info('setAVPlaybackState successfully');}).catch((err) => {console.info(`setAVPlaybackState : ERROR : ${err.message}`);});mediaFavorite = favorite;
});// 注册媒体按键命令监听
currentSession.on('handleKeyEvent', (event) => {console.log(`用户按键 ${event.keyCode}`);
});// 注册播放设备变化命令监听
currentSession.on('outputDeviceChange', (device) => {console.log(`输出设备变更,更新显示 ${device.deviceName}`);
});

5.释放资源

// 取消注册回调
currentSession.off('play');
currentSession.off('pause');
currentSession.off('stop');
currentSession.off('playNext');
currentSession.off('playPrevious');
currentSession.off('fastForward');
currentSession.off('rewind');
currentSession.off('seek');
currentSession.off('setSpeed');
currentSession.off('setLoopMode');
currentSession.off('toggleFavorite');
currentSession.off('handleKeyEvent');
currentSession.off('outputDeviceChange');// 去激活session并销毁对象
currentSession.deactivate().then(() => {currentSession.destroy();
});

调测验证

在媒体应用上点击播放、暂停、下一首等按键,媒体播放状态出现相应变化。

常见问题

1.会话服务端异常 - 现象描述:

会话服务端异常,应用端无法获取服务端的消息响应。如会话服务未运行或者会话服务通信失败。返回错误信息: Session service exception。

  • 可能原因:

会话重启过程中服务被杀。

  • 解决办法

(1)定时重试,超过3s仍失败时,停止对该会话或者控制器进行操作。

(2)销毁当前会话或者会话控制器,并重新创建,如果重新创建失败,则停止会话相关操作。

2.会话不存在 - 现象描述:

会话对象不存在时,向该会话设置参数或者发送命令。返回错误信息: The session does not exist。

  • 可能原因:

会话已被销毁,服务端无会话记录。

  • 解决办法

(1)如果在会话被控端产生该错误,请重新创建会话;如果是会话控制端,请停止向该会话发送查询或者控制命令。

(2)如果在会话管理端产生该错误,请重新查询系统当前会话记录,在创建控制器时传入正确的会话ID。

3.会话未激活 - 现象描述:

会话没有激活时,向会话发送控制命令或者事件。。返回错误信息: The session not active。

  • 可能原因:

会话处于未激活状态。

  • 解决办法

停止发送该命令或事件,监听会话的激活状态,会话激活后恢复发送该命令或事件。

相关实例

提供音乐Demo的代码实例

会话控制端开发指导(播控中心)

基本概念

  • 远端投播:将本地媒体投播到远端设备,通过本地控制器发送命令,可控制远端播放行为。
  • 发送按键命令:控制器通过发送按键事件的方式控制媒体。
  • 发送控制命令:控制器通过发送控制命令的方式控制媒体。
  • 发送系统按键命令:应用拥有调用该接口的系统权限,通过发送按键事件的方式控制媒体,仅系统应用可用。
  • 发送系统控制命令:应用拥有调用该接口的系统权限,通过发送控制命令的方式控制媒体,仅系统应用可用。

接口说明

会话控制端涉及的常用接口如下表所示。接口返回值有两种返回形式:callback和promise,下表中为callback形式接口,promise和callback只是返回值方式不一样,功能相同。更多API说明请参见API文档。

表2:会话控制端常用接口

接口名描述
getAllSessionDescriptors(callback: AsyncCallback<Array<Readonly>>): void获取所有会话的描述符
createController(sessionId: string, callback: AsyncCallback): void创建控制器
sendAVKeyEvent(event: KeyEvent, callback: AsyncCallback): void发送按键命令
getLaunchAbility(callback: AsyncCallback): void拉起应用
sendControlCommand(command: AVControlCommand, callback: AsyncCallback): void发送控制命令
sendSystemAVKeyEvent(event: KeyEvent, callback: AsyncCallback): void发送系统按键命令
sendSystemControlCommand(command: AVControlCommand, callback: AsyncCallback): void发送系统控制命令
castAudio(session: SessionToken‘all’, audioDevices: Array<audio.AudioDeviceDescriptor>, callback: AsyncCallback): void

开发步骤

1.导入模块接口

import avSession from '@ohos.multimedia.avsession';
import {Action, KeyEvent} from '@ohos.multimodalInput.KeyEvent';
import wantAgent from '@ohos.app.ability.wantAgent';
import audio from '@ohos.multimedia.audio';

2.获取会话描述符,创建控制器

// 全局变量定义
let g_controller = new Array<avSession.AVSessionController>();
let g_centerSupportCmd:Set<avSession.AVControlCommandType> = new Set(['play', 'pause', 'playNext', 'playPrevious', 'fastForward', 'rewind', 'seek','setSpeed', 'setLoopMode', 'toggleFavorite']);
let g_validCmd:Set<avSession.AVControlCommandType>;// 获取会话描述符,创建控制器
avSession.getAllSessionDescriptors().then((descriptors) => {descriptors.forEach((descriptor) => {avSession.createController(descriptor.sessionId).then((controller) => {g_controller.push(controller);}).catch((err) => {console.error('createController error');});});
}).catch((err) => {console.error('getAllSessionDescriptors error');
});// 注册会话创建监听,创建控制器
avSession.on('sessionCreate', (session) => {// 新增会话,需要创建控制器avSession.createController(session.sessionId).then((controller) => {g_controller.push(controller);}).catch((err) => {console.info(`createController : ERROR : ${err.message}`);});
});

3.监听AVSession会话状态以及AVSession服务变化

// 注册会话激活状态变更监听
controller.on('activeStateChange', (isActive) => {if (isActive) {console.log("控制器卡片按键高亮");} else {console.log("控制器卡片按键变更为无效");}
});// 注册会话销毁监听
controller.on('sessionDestroy', () => {console.info('on sessionDestroy : SUCCESS ');controller.destroy().then(() => {console.info('destroy : SUCCESS ');}).catch((err) => {console.info(`destroy : ERROR :${err.message}`);});
});// 注册系统会话销毁监听
avSession.on('sessionDestroy', (session) => {let index = g_controller.findIndex((controller) => {return controller.sessionId == session.sessionId;});if (index != 0) {g_controller[index].destroy();g_controller.splice(index, 1);}
});// 注册系统最高优先级会话变更监听
avSession.on('topSessionChange', (session) => {let index = g_controller.findIndex((controller) => {return controller.sessionId == session.sessionId;});// 将该会话显示排到第一个if (index != 0) {g_controller.sort((a, b) => {return a.sessionId == session.sessionId ? -1 : 0;});}
});// 注册服务异常监听
avSession.on('sessionServiceDie', () => {// 服务端异常,应用清理资源console.log("服务端异常");
})

4.监听AVSession会话信息变化

// 注册元数据更新监听
let metaFilter = ['assetId', 'title', 'description'];
controller.on('metadataChange', metaFilter, (metadata) => {console.info(`on metadataChange assetId : ${metadata.assetId}`);
});// 注册播放状态更新监听
let playbackFilter = ['state', 'speed', 'loopMode'];
controller.on('playbackStateChange', playbackFilter, (playbackState) => {console.info(`on playbackStateChange state : ${playbackState.state}`);
});// 注册会话支持的命令变更监听
controller.on('validCommandChange', (cmds) => {console.info(`validCommandChange : SUCCESS : size : ${cmds.size}`);console.info(`validCommandChange : SUCCESS : cmds : ${cmds.values()}`);g_validCmd.clear();for (let c of g_centerSupportCmd) {if (cmds.has(c)) {g_validCmd.add(c);}}
});// 注册输出设备变更监听
controller.on('outputDeviceChange', (device) => {console.info(`on outputDeviceChange device isRemote : ${device.isRemote}`);
});

5.控制AVSession会话行为

// 用户点击播放按键:发送控制命令--播放
if (g_validCmd.has('play')) {controller.sendControlCommand({command:'play'}).then(() => {console.info('sendControlCommand successfully');}).catch((err) => {console.info(`sendControlCommand : ERROR : ${err.message}`);});
}// 用户点击循环模式:发送控制命令--单曲循环
if (g_validCmd.has('setLoopMode')) {controller.sendControlCommand({command: 'setLoopMode', parameter: avSession.LoopMode.LOOP_MODE_SINGLE}).then(() => {console.info('sendControlCommand successfully');}).catch((err) => {console.info(`sendControlCommand : ERROR : ${err.message}`);});
}// 发送按键事件
let keyItem = {code: 0x49, pressedTime: 123456789, deviceId: 0};
let event = {action: 2, key: keyItem, keys: [keyItem]};
controller.sendAVKeyEvent(event).then(() => {console.info('sendAVKeyEvent Successfully');
}).catch((err) => {console.info(`sendAVKeyEvent : ERROR : ${err.message}`);
});// 用户点击卡片空白位置拉起应用
controller.getLaunchAbility().then((want) => {console.log("前台拉起应用");
}).catch((err) => {console.info(`getLaunchAbility : ERROR : ${err.message}`);
});// 发送系统媒体按键事件
let keyItem = {code: 0x49, pressedTime: 123456789, deviceId: 0};
let event = {action: 2, key: keyItem, keys: [keyItem]};
avSession.sendSystemAVKeyEvent(event).then(() => {console.info('sendSystemAVKeyEvent Successfully');
}).catch((err) => {console.info(`sendSystemAVKeyEvent : ERROR : ${err.message}`);
});// 发送系统控制命令,系统会把控制命令发送到Top会话中
let avcommand = {command: 'toggleFavorite', parameter: "false"};
avSession.sendSystemControlCommand(avcommand).then(() => {console.info('sendSystemControlCommand successfully');
}).catch((err) => {console.info(`sendSystemControlCommand : ERROR : ${err.message}`);
});// 投播到其他设备
let audioManager = audio.getAudioManager();
let audioDevices;
await audioManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG).then((data) => {audioDevices = data;console.info('Promise returned to indicate that the device list is obtained.');
}).catch((err) => {console.info(`getDevices : ERROR : ${err.message}`);
});avSession.castAudio('all', audioDevices).then(() => {console.info('createController : SUCCESS');
}).catch((err) => {console.info(`createController : ERROR : ${err.message}`);
});

6.释放资源

// 取消注册回调controller.off('metadataChange');controller.off('playbackStateChange');controller.off('sessionDestroy');controller.off('activeStateChange');controller.off('validCommandChange');controller.off('outputDeviceChange');// 销毁controller对象controller.destroy().then(() => {console.info('destroy : SUCCESS ');}).catch((err) => {console.info(`destroy : ERROR : ${err.message}`);});

调测验证

在播控中心点击播放、暂停、下一首等按键,应用播放状态随即发生相应变化。

常见问题

1.控制器不存在 - 现象描述:

会话控制器不存在时,向该控制器发送控制命令或者事件。返回错误信息: The session controller does not exist。

  • 可能原因:

控制器已被销毁。

  • 解决办法

请重新查询系统当前会话记录,并创建对应的会话控制器。

2.远端会话连接失败 - 现象描述:

本端会话与远端会话通信失败。返回错误信息: The remote session connection failed。

  • 可能原因:

设备间通信断开。

  • 解决办法

停止对该会话发送控制命令,并监听输出设备变化,当输出设备发送变化后恢复发送。

3.无效会话命令 - 现象描述:

会话被控端不支持该被控命令或事件。返回错误信息: Invalid session command。

  • 可能原因:

被控端不支持该命令。

  • 解决办法

停止发送该命令或事件,并查询被控会话支持的命令集,发送被控端支持的命令。

4.消息过载 - 现象描述:

会话客户端在一段时间内向服务端发送了过多的消息或者命令,引起服务端消息过载。返回错误信息: Command or event overload。

  • 可能原因:

服务端消息过载。

  • 解决办法

检查自身命令发送是否过于频繁,控制自身查询和控制命令的发送频度。

为了能让大家更好的学习鸿蒙 (OpenHarmony) 开发技术,这边特意整理了《鸿蒙 (OpenHarmony)开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙 (OpenHarmony)开发学习手册》

入门必看:https://qr21.cn/FV7h05

  1. 应用开发导读(ArkTS)
  2. ……

HarmonyOS 概念:https://qr21.cn/FV7h05

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

如何快速入门?:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. 构建第一个JS应用
  4. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/660328.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

17. Spring Boot Actuator

17. Spring Boot Actuator Spring Boot执行器(Actuator)提供安全端点&#xff0c;用于监视和管理Spring Boot应用程序。 默认情况下&#xff0c;所有执行器端点都是安全的。 在本章中&#xff0c;将详细了解如何为应用程序启用Spring Boot执行器。 启用Spring Boot Actuator …

光纤熔接-热熔

实验教学日的及具体要求 目的 1.掌握室外光缆、皮线光缆的开剥方法。 2.掌握应用光纤切割刀制作光纤端面的方法 3.掌握光纤熔接的基本知识。 4.掌握光纤熔接机的使用方法及接续步骤。 任务 1.完成2芯光缆在终端盒内与尾纤的熔接 2.用激光笔完成光纤熔接检测。 …

如何使用mock.js实现接口测试的自动化?

Mock.js 基础用法介绍 Mock.js是一个常用于生成随机数据和拦截Ajax请求的JavaScript库。本文将介绍Mock.js的用法&#xff0c;包括安装和基础用法&#xff0c;在开始前我们可以看下看&#xff1a;了解 Mock.js 的语法规范。 安装 可以通过npm安装Mock.js&#xff1a; npm i…

敏捷认证大热:PMI-ACP

你是否在寻找一个能让你在不断变化的职场环境中脱颖而出的认证&#xff1f;PMI-ACP正是你需要的&#xff01;这个由美国项目管理协会PMI颁发的认证&#xff0c;是全球敏捷项目管理领域的权威代表。无论你是希望转型到项目管理领域&#xff0c;还是想提升现有项目管理技能&#…

Kafka下载安装及基本使用

目录 Kafka介绍 消息队列的作用 消息队列的优势 应用解耦 异步提速 削峰填谷 为什么要用Kafka Kafka下载安装 Kafka快速上手&#xff08;单机体验&#xff09; 1. 启动zookeeper服务 2. 启动kafka服务 3. 简单收发消息 Kakfa的消息传递机制 Kafka介绍 Apache Kafka…

模拟实现哈希表 - HashMap(Java版本)

目录 1. 概念 2. 冲突-概念 3. 冲突-避免 4. 冲突-避免-哈希函数设计 5. 冲突-避免-负载因子调节 ⭐⭐⭐⭐⭐ 6. 冲突-解决 6.1 冲突-解决-闭散列 6.2 冲突-解决-开散列/哈希桶 ⭐⭐⭐⭐⭐ 7. 冲突严重时的解决办法 8. 模拟实现 1. 概念 顺序结构以及平衡树中&#…

揭开时间序列的神秘面纱:特征工程的力量

目录 写在开头1. 什么是特征工程?1.1 特征工程的定义和基本概念1.2 特征工程在传统机器学习中的应用1.3 时间序列领域中特征工程的独特挑战和需求3. 时间序列数据的特征工程技术2.1 数据清洗和预处理2.1.1 缺失值处理2.1.2 异常值检测与处理2.2 时间特征的提取2.2.1 时间戳解析…

MySQL基础(三)-学习笔记

一.innodb引擎&#xff1a; 1). 表空间&#xff1a;表空间是InnoDB存储引擎逻辑结构的最高层&#xff0c;启用了参数 innodb_file_per_table(在 8.0版本中默认开启) &#xff0c;则每张表都会有一个表空间&#xff08;xxx.ibd&#xff09;&#xff0c;一个mysql实例可以对应多个…

计算机网络——网络层(3)

计算机网络——网络层&#xff08;3&#xff09; 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU)1 网络层——控制平面因特网中自治系统内部的路由选择总括考虑因素总结 ISP之间的路由选择&#xff1a;BGP考虑因素总结 SDN控制层面重要组件和功能总结 ICMP主要功能和特点…

京东手机评论分析

文章目录 前言:数据处理1.1数据导入1.2数据描述1.3数据预处理 2.情感分析2.1情感分析安装snownlp包 2.2 情感分直方图情感分直方图 2.3 词云图2.4 关键词提取关键词top10 3 积极评论与消极评论3.1 积极评论与消极评论占比计算积极评论与消极评论各自的数目积极评论占比 3.2 消极…

大脑模型认知实验报告(脑与认知期末考核)

实验名称&#xff1a;大脑模型认知实验 实验目的&#xff1a; &#xff08;1&#xff09;对大脑的三部分、七层结构、区域划分有一个清晰的认识。 &#xff08;2&#xff09;对脑的各个区域的基本功能以及脑的工作方式有所了解。 实验环境&#xff1a;大脑模具、配有详细标…

Mongodb安装Linux

确定你的CentOS 版本 使用以下命令: /etc/centos-release下载Mongodb 解压tgz压缩包 创建data和log文件夹 , 确定你的文件夹访问权限 在log文件夹里面创建mongodb.log文件(这一步很重要 ! ! !) touch mongodb.log创建mongodb.conf文件 在你的mongodb文件夹下 vi mongo…

Flink 1.18.1 部署与配置 [CentOS7]

静态IP设置 # 修改网卡配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33# 修改文件内容 TYPEEthernet PROXY_METHODnone BROWSER_ONLYno BOOTPROTOstatic IPADDR192.168.18.128 NETMASK255.255.255.0 GATEWAY192.168.18.2 DEFROUTEyes IPV4_FAILURE_FATALno IPV6INIT…

如何本地搭建Emby影音管理服务并结合内网穿透实现远程访问本地影音库

文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中&#xff0c;观看视频绝对是主力应用场景之一&…

6个AI写作工具,让你的文字变得生动有力

写作是一项需要耐心和技巧的任务&#xff0c;对于许多人来说&#xff0c;写作可能是一项困难的挑战。然而&#xff0c;随着人工智能的发展&#xff0c;AI智能写作软件逐渐崭露头角&#xff0c;为我们提供了更加便捷和高效的写作体验。在本文中&#xff0c;我们将介绍几款好用的…

Spring-mybatis

怎样通过Spring整合Mybatis来实现业务 目录 1.导入依赖 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency>&l…

一文教你如何本地搭建Qchan图床网站实现公网远程访问

文章目录 前言1. Qchan网站搭建1.1 Qchan下载和安装1.2 Qchan网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar云端设置2.2 Cpolar本地设置 3. 公网访问测试总结 前言 图床作为云存储的一项重要应用场景&#xff0c;在大量开发人员的努力下&#xff0c;已经开发出大…

代码随想录 Leetcode77.组合

题目&#xff1a; 代码&#xff08;首刷看解析 2024年2月1日&#xff09;&#xff1a; class Solution { public:vector<vector<int>> res;vector<int> path;void backtracing(int n, int k, int startIndex) {if (path.size() k) {res.push_back(path);re…

windows pm2 执行 npm脚本或执行yarn脚本遇到的问题及解决方案

环境&#xff1a; 在windows上启动终端来运行一个项目&#xff1b;通过指令npm run start来启动&#xff0c;但是将终端一关&#xff0c;就无法访问了&#xff0c;所以想到用pm2来管理 1. 全局安装pm2 npm i pm2 -g2. 在项目根目录执行指令(大部分兄弟的错误使用方法) pm2 st…

微信小程序(二十七)列表渲染改变量名

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.改变默认循环单元item变量名 2.改变默认循环下标index变量名 基础模板有问题可以先看上一篇 源码&#xff1a; index.wxml <view class"students"><view class"item"><te…