公司企业建站报价/女教师网课入侵录屏

公司企业建站报价,女教师网课入侵录屏 ,国家企业信息年报系统,建设营销网站多少钱1. 核心组件 MusicCacheManager (音乐缓存管理器) 单例模式:确保全局只有一个实例,方便管理。 private static var instance: MusicCacheManager?static func shared() -> MusicCacheManager {if instance nil {instance MusicCacheManager()}ret…

1. 核心组件

MusicCacheManager (音乐缓存管理器)
  • 单例模式:确保全局只有一个实例,方便管理。

    private static var instance: MusicCacheManager?static func shared() -> MusicCacheManager {if instance == nil {instance = MusicCacheManager()}return instance!
    }
    
  • 文件管理:使用FileManager管理缓存目录和文件操作。

    private let fileManager = FileManager.default
    private let musicCacheDirectory: URL
    
  • URLSession:用于下载音乐文件,配置忽略系统代理设置。

    private lazy var session: URLSession = {let config = URLSessionConfiguration.defaultconfig.connectionProxyDictionary = [:] // 忽略系统代理设置return URLSession(configuration: config)
    }()
    

2. 主要功能实现

缓存存储
  • 缓存路径:每个音乐文件使用唯一的缓存键(歌曲ID_标题.mp3)进行存储。

    private func getCacheKey(for song: Songs) -> String {return "\(song.id)_\(song.title.replacingOccurrences(of: " ", with: "_")).mp3"
    }
    
  • 检查缓存:判断文件是否已缓存。

    func isCached(song: Songs) -> Bool {return getCachedPath(for: song) != nil
    }
    
缓存下载
  • 下载任务:使用URLSession下载音乐文件,下载完成后将临时文件移动到缓存目录。

    func cacheSong(_ song: Songs, withUrl url: String, completion: @escaping (String?, Error?) -> Void) {guard let downloadUrl = URL(string: url) else {completion(nil, NSError(domain: "MusicCacheManager", code: 1001, userInfo: [NSLocalizedDescriptionKey: "无效的歌曲URL"]))return}let cacheKey = getCacheKey(for: song)let destinationPath = musicCacheDirectory.appendingPathComponent(cacheKey).path// 检查是否已经缓存if fileManager.fileExists(atPath: destinationPath) {completion(destinationPath, nil)return}// 创建下载任务let downloadTask = session.downloadTask(with: downloadUrl) { [weak self] (tempURL, response, error) inguard let self = self else { return }if let error = error {completion(nil, error)return}guard let tempURL = tempURL else {completion(nil, NSError(domain: "MusicCacheManager", code: 1003, userInfo: [NSLocalizedDescriptionKey: "下载临时文件URL为空"]))return}do {// 将临时文件移动到目标位置try self.fileManager.moveItem(at: tempURL, to: URL(fileURLWithPath: destinationPath))completion(destinationPath, nil)} catch {completion(nil, error)}}// 开始下载downloadTask.resume()
    }
    
缓存管理
  • 清理缓存:当缓存超过最大限制时自动触发清理,基于LRU(最近最少使用)算法清理旧文件。

    private func cleanupCache() {do {let cacheInfo = cacheConfig.loadCacheInfo()let cachedFiles = try fileManager.contentsOfDirectory(at: musicCacheDirectory, includingPropertiesForKeys: nil)// 将文件按最后访问时间排序let sortedFiles = cachedFiles.sorted { (url1, url2) -> Bool inlet key1 = url1.lastPathComponentlet key2 = url2.lastPathComponentlet time1 = cacheInfo[key1] ?? 0let time2 = cacheInfo[key2] ?? 0return time1 < time2}// 如果缓存超出限制,删除最早访问的文件var newSize = currentSizevar newCacheInfo = cacheInfofor fileURL in sortedFiles {if newSize <= cacheConfig.maxCacheSize * UInt64(0.8) {break}let key = fileURL.lastPathComponentdo {let attributes = try fileManager.attributesOfItem(atPath: fileURL.path)if let fileSize = attributes[.size] as? UInt64 {try fileManager.removeItem(at: fileURL)newSize -= fileSizenewCacheInfo.removeValue(forKey: key)}} catch {print("清理缓存文件失败: \(error.localizedDescription)")}}// 保存更新后的缓存信息cacheConfig.saveCacheInfo(newCacheInfo)} catch {print("执行缓存清理失败: \(error.localizedDescription)")}
    }
    

3. 智能缓存策略

  • 自动缓存控制:通过MusicPlayerManagerautoCache属性控制是否自动缓存。

    var autoCache: Bool = true
    
  • 缓存优先级:播放时优先使用缓存文件,无缓存时从网络加载并同时进行缓存。

    if let cachedPath = cacheManager.getCachedPath(for: data) {playLocalMusic(uri: cachedPath, data: data)
    } else {playNetworkMusic(uri: uri, data: data)if autoCache {cacheManager.cacheSong(data) { (cachedPath, error) in// 处理缓存结果}}
    }
    

4. 性能优化

  • 异步操作:所有文件操作在后台线程执行,使用DispatchQueue确保线程安全。

  • 网络优化:自定义URLSession配置,忽略系统代理设置提高下载速度,设置合理的超时时间。

    config.timeoutIntervalForResource = 60.0 // 资源超时时间为60秒
    config.timeoutIntervalForRequest = 30.0 // 请求超时时间为30秒
    

通过这样的设计,音乐缓存系统能够有效提升音乐播放的流畅度,减少网络请求,优化用户体验。

在这里插入图片描述

关于断点重传机制:

// ... existing code .../// 保存下载进度数据
private var resumeDataDict: [String: Data] = [:]/// 缓存歌曲,使用指定的URL
///
/// - Parameters:
///   - song: 歌曲对象
///   - url: 下载地址
///   - completion: 完成回调,参数为缓存后的本地路径和可能的错误
func cacheSong(_ song: Songs, withUrl url: String, completion: @escaping (String?, Error?) -> Void) {guard let downloadUrl = URL(string: url) else {completion(nil, NSError(domain: "MusicCacheManager", code: 1001, userInfo: [NSLocalizedDescriptionKey: "无效的歌曲URL"]))return}let cacheKey = getCacheKey(for: song)let destinationPath = musicCacheDirectory.appendingPathComponent(cacheKey).path// 检查是否已经缓存if fileManager.fileExists(atPath: destinationPath) {print("歌曲已缓存: \(song.title)")completion(destinationPath, nil)return}// 检查是否正在下载if let _ = downloadTasks[cacheKey] {print("歌曲正在下载中: \(song.title)")completion(nil, NSError(domain: "MusicCacheManager", code: 1002, userInfo: [NSLocalizedDescriptionKey: "歌曲正在下载中"]))return}print("开始下载歌曲: \(song.title), URL: \(url)")// 创建下载任务let downloadTask: URLSessionDownloadTask// 检查是否有可恢复的数据if let resumeData = resumeDataDict[cacheKey] {print("使用断点续传数据继续下载: \(song.title)")downloadTask = session.downloadTask(withResumeData: resumeData)// 清除已使用的恢复数据resumeDataDict.removeValue(forKey: cacheKey)} else {downloadTask = session.downloadTask(with: downloadUrl)}// 设置完成回调downloadTask.taskDescription = cacheKey// 将任务添加到队列downloadTasks[cacheKey] = downloadTask// 设置完成处理器downloadTask.resume()
}/// 取消下载
///
/// - Parameter song: 歌曲对象
func cancelDownload(for song: Songs) {let cacheKey = getCacheKey(for: song)if let task = downloadTasks[cacheKey] {// 使用byProducingResumeData方法取消,以获取恢复数据task.cancel(byProducingResumeData: { [weak self] data inguard let self = self else { return }if let data = data {// 保存恢复数据以便后续使用self.resumeDataDict[cacheKey] = dataprint("已保存断点续传数据: \(song.title)")}self.downloadTasks.removeValue(forKey: cacheKey)print("已取消下载: \(song.title)")})}
}// 需要添加URLSessionDownloadDelegate方法来处理下载完成事件
extension MusicCacheManager: URLSessionDownloadDelegate {func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {guard let cacheKey = downloadTask.taskDescription else { return }// 从下载任务队列中移除downloadTasks.removeValue(forKey: cacheKey)// 获取目标路径let destinationPath = musicCacheDirectory.appendingPathComponent(cacheKey).pathdo {// 如果目标文件已存在,先删除if fileManager.fileExists(atPath: destinationPath) {try fileManager.removeItem(atPath: destinationPath)}// 将临时文件移动到目标位置try fileManager.moveItem(at: location, to: URL(fileURLWithPath: destinationPath))print("歌曲缓存成功: \(cacheKey), 路径: \(destinationPath)")// 更新最后访问时间updateAccessTime(for: cacheKey)// 查找对应的回调并执行// 这里需要维护一个回调字典,或者通过其他方式找到对应的回调// 简化起见,这里省略了回调处理} catch {print("保存缓存文件失败: \(error.localizedDescription)")}}func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {guard let downloadTask = task as? URLSessionDownloadTask,let cacheKey = downloadTask.taskDescription else { return }// 从下载任务队列中移除downloadTasks.removeValue(forKey: cacheKey)if let error = error as NSError? {// 检查是否是取消错误,并且有恢复数据if error.code == NSURLErrorCancelled && error.userInfo[NSURLSessionDownloadTaskResumeData] != nil {// 已经在cancelDownload方法中处理了恢复数据,这里不需要额外处理} else {print("下载任务失败: \(cacheKey), 错误: \(error.localizedDescription)")}}}
}// 初始化方法中需要修改session的创建方式
private init() {// ... existing code ...// 创建URL会话,使用self作为代理session = URLSession(configuration: config, delegate: self, delegateQueue: nil)// ... existing code ...
}// ... existing code ...

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

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

相关文章

阿里开源的免费数据集成工具——DataX

企业里真实的数据流转是什么样子的呢&#xff1f; 左侧描述了一个企业真实的样子&#xff0c;我们总是需要把数据从一个地方搬到另一个地方&#xff0c;最后就是搬来搬去搬成了一张张解不开的网。 右侧则表达了使用DataX为中心实现数据的同步。 什么是DataX DataX是一个异构…

26考研——图_图的遍历(6)

408答疑 文章目录 三、图的遍历图的遍历概述图的遍历算法的重要性图的遍历与树的遍历的区别图的遍历过程中的注意事项避免重复访问遍历算法的分类遍历结果的不唯一性 广度优先搜索广度优先搜索&#xff08;BFS&#xff09;概述BFS 的特点广度优先遍历的过程示例图遍历过程 BFS …

前端解决方案:实现网页截图并导出PDF功能

前端解决方案&#xff1a;实现网页截图并导出PDF功能 在前端开发中&#xff0c;我们经常会遇到需要将网页内容导出为PDF的需求。本文将以一个准考证预览和导出的例子&#xff0c;带你一步步实现这个功能。我们会处理包括跨域图片、Canvas绘图、PDF生成等多个技术要点。 一、基…

【MySQL】表操作

表操作 一、创建表 1、语句2、语句介绍3、注意事项4、介绍5、示例 二、查看表结构 1、语句2、介绍3、返回的信息4、示例 三、添加字段 1、语句2、语句介绍3、示例 四、修改 1、语句2、语句介绍3、示例 五、删除 1、语句2、示例 六、修改表名 1、语句2、语句介绍3、示例 七、删…

响应“一机两用”政策 ,实现政务外网安全

在数字化办公的浪潮下&#xff0c;企业与政务机构面临着既要保障数据安全&#xff0c;又要高效访问互联网的双重需求。“一机两用”成为解决这一难题的关键。 政策驱动&#xff0c;需求迫切 随着《网络安全法》《数据安全法》等法律法规的相继出台&#xff0c;网络安全防护的要…

文生图语义识别插件使用(controlnet)

1. 插件下载(github) https://github.com/Mikubill/sd-webui-controlnet https://github.com/lllyasviel/ControlNet2. 模型下载(hugging face) https://github.com/Mikubill/sd-webui-controlnet/wiki/Model-download https://huggingface.co/bdsqlsz/qinglong_controlnet-l…

学者观察 | web3.0产业发展与技术融合——北京大学研究员肖臻

导语 肖臻老师认为在未来很长一段时间内&#xff0c;Web 3.0将和现在的Web 2.0共存。Web 3.0和人工智能&#xff08;AI&#xff09;的融合发展前景非常广阔&#xff0c;Web 3.0致力于打造去中心化的互联网生态系统&#xff0c;赋予用户更大的数据所有权和控制权&#xff0c;而…

【模型压缩+推理加速】知识蒸馏综述解读

知识蒸馏综述解读 论文&#xff1a; https://arxiv.org/abs/2006.05525 最近Deepseek R1的技术报告中&#xff0c;训练部分提到使用了知识蒸馏&#xff0c;就像系统性的看看蒸馏算法的原理。看了很多的博客&#xff0c;很多都没有详细把知识蒸馏系统的讲清楚。我们还是读一下…

vivo 湖仓架构的性能提升之旅

作者&#xff1a;郭小龙 vivo互联网 大数据高级研发工程师 导读&#xff1a;本文整理自 vivo互联网 大数据高级研发工程师 郭小龙 在 StarRocks 年度峰会上的分享&#xff0c;聚焦 vivo 大数据多维分析面临的挑战、StarRocks 落地方案及应用收益。 在 即席分析 场景&#xff0c…

2025年如何避免使用验证码求解器时被IP封禁

引言 2025年&#xff0c;验证码求解器已成为自动化网络抓取和其他在线流程的关键工具。然而&#xff0c;自动化用户面临的一个常见挑战是IP封禁。当网站检测到自动化活动时&#xff0c;通常会阻止发出请求的IP地址&#xff0c;导致验证码挑战无法解决。本文将探讨使用验证码求…

JVM详解(包括JVM内存模型与GC垃圾回收)

&#x1f4d6;前言&#xff1a; 学会使用Java对于一个程序员是远远不够的。Java语法的掌握只是一部分&#xff0c;另一部分就是需要掌握Java内部的工作原理&#xff0c;从编译到运行&#xff0c;到底是谁在帮我们完成工作的&#xff1f; 接下来着重对Java虚拟机&#xff0c;也就…

【无标题】大亚湾文化体育场多美啊。

请推荐一些常用并且免费的&#xff0c;可直接在线运行【Python】代码的平台并列出对应网址 好的&#xff0c;用户想让我推荐一些常用且免费的、可以直接在线运行Python代码的平台&#xff0c;并且需要列出对应的网址。我需要先回想一下自己知道的在线Python运行环境&#xff0…

权限提升—Windows权限提升土豆家族溢出漏洞通杀全系

前言 OK&#xff0c;Java安全更新不下去了&#xff0c;实在是太难啦啊&#xff0c;想起来提权这一块没怎么更新过&#xff0c;接下来都主要是更新提权这一块的文章了&#xff0c;Java安全的话以后有耐心再搞了。 手动提权 今天主要是讲这个手动的提权&#xff0c;手动提权相…

python --face_recognition(人脸识别,检测,特征提取,绘制鼻子,眼睛,嘴巴,眉毛)/活体检测

dlib 安装方法 之前博文 https://blog.csdn.net/weixin_44634704/article/details/141332644 环境: python3.8 opencv-python4.11.0.86 face_recognition1.3.0 dlib19.24.6人脸检测 import cv2 import face_recognition# 读取人脸图片 img cv2.imread(r"C:\Users\123\…

禾赛盈利了,但激光雷达没有胜利

还远没有到激光雷达党欢呼的时候。 3月&#xff0c;随着禾赛科技公布2024年报&#xff0c;全世界第一家也是唯一一家实现全年盈利的激光雷达上市公司诞生&#xff0c;为了这个盈利目标&#xff0c;禾赛科技奋斗了十年。 但极大的出货量和不高的盈利水平&#xff0c;让禾赛科技…

关于金碟K3,禁用和启用需要流程审批后执行

真是难受,是设计师蠢呢自己问题比较多呢,现在都还没有弄好 点击禁用和启用,通过流程来执行 到底是蠢呢还是设计问题,搞了半日没有效果,搞那么复杂! 而且有样板都没有草鞋成功 BOS设计,表单属性,操作列表: 1、启用禁用流程

导入 Excel 规则批量修改或删除 PDF 文档内容

需要对 PDF 文档内容进行修改的时候&#xff0c;通常我们会需要借助一些专业的工具来帮我们完成。那我们如果需要修改的 PDF 文档较多的时候&#xff0c;有什么方法可以帮我们实现批量操作呢&#xff1f;今天这篇文章就给大家介绍一下当我们需要批量修改多个 PDF 文档的时候&am…

msyql--基本操作之运维篇

检查 root 用户的权限 查看该用户针对这个数据库的权限 -- 如果在终端连接mysql时需要 mysql -u root -p -- 查看用户权限 SELECT user, host FROM mysql.user WHERE user root;可以看的出来root有他的访问权限&#xff0c;如过没有localhost或者% 说明没有访问权限 添加…

云计算:探索现代科技的未来之云

文章目录 云计算基本概念云计算是什么注意 云计算的价值云计算的部署模式云计算的服务模式主流的云计算技术AWS简介AWS建立了广阔的合作伙伴生态 VMware简介VMware服务介绍 华为云简介华为云Stack模式 云计算基本概念 云计算是什么 云计算是一种模型&#xff0c;它可以实现随时…

STM32蜂鸣器播放音乐

STM32蜂鸣器播放音乐 STM32蜂鸣器播放音乐 Do, Re, Mi, Fa, 1. 功能概述 本系统基于STM32F7系列微控制器&#xff0c;实现了以下功能&#xff1a; 通过7个按键控制蜂鸣器发声&#xff0c;按键对应不同的音符。每个按键对应一个音符&#xff08;Do, Re, Mi, Fa, Sol, La, Si&a…