AVAudioPlayer持续重启求助:基于速度触发的地图警示音异常
问题解决:避免速度更新时警示音反复重启
你的核心问题是每次位置更新都调用play(),导致音频从头重复播放,同时还存在音频播放器未初始化的问题。以下是针对性的修复方案:
关键问题分析
- 音频播放器
player从未初始化:sesFonk()方法没被调用,导致player始终为nil,一开始根本无法播放声音。 - 无状态判断:只要速度≥7就调用
play(),而AVAudioPlayer的play()在播放中会从头重启,导致声音反复中断。
修复后的完整代码
import UIKit import MapKit import CoreLocation import AVFoundation class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate { @IBOutlet weak var imageLabel: UIImageView! @IBOutlet weak var mapView: MKMapView! var player: AVAudioPlayer! var locationManager = CLLocationManager() // 新增状态变量:记录警示音是否正在播放 var isWarningSoundPlaying = false override func viewDidLoad() { super.viewDidLoad() mapView.delegate = self imageLabel.isHidden = true // 初始化音频播放器(必须调用,否则player为nil) sesFonk() locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.delegate = self locationManager.requestWhenInUseAuthorization() locationManager.startUpdatingLocation() } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { // 安全获取最新位置,避免数组越界 guard let sonKonum = locations.last else { return } let konum = sonKonum.coordinate let span = MKCoordinateSpan(latitudeDelta: 0.03, longitudeDelta: 0.03) let bolge = MKCoordinateRegion(center: konum, span: span) mapView.setRegion(bolge, animated: true) mapView.showsUserLocation = true let currentSpeed = Int(sonKonum.speed) print(currentSpeed) if currentSpeed >= 7 { imageLabel.isHidden = false // 只有当声音未播放时,才启动播放 if !isWarningSoundPlaying { player?.play() isWarningSoundPlaying = true } } else { imageLabel.isHidden = true // 只有当声音正在播放时,才停止并重置播放位置 if isWarningSoundPlaying { player?.stop() player?.currentTime = 0 isWarningSoundPlaying = false } } } func sesFonk() { guard let url = Bundle.main.url(forResource: "yavas", withExtension: "mp3") else { print("错误:找不到音频文件yavas.mp3") return } do { player = try AVAudioPlayer(contentsOf: url) // 设置无限循环播放(适合警示场景) player.numberOfLoops = -1 // 预加载音频,避免播放卡顿 player.prepareToPlay() } catch { print("初始化音频播放器失败:\(error.localizedDescription)") } } }
核心修改说明
- 新增状态变量
isWarningSoundPlaying:用来追踪当前警示音的播放状态,只有状态变化时才执行播放/停止操作,避免重复触发。 - 初始化音频播放器:在
viewDidLoad中调用sesFonk(),确保player被正确初始化。 - 优化播放逻辑:仅当速度超过阈值且声音未播放时启动播放;速度低于阈值且声音在播放时停止并重置播放位置。
- 增强错误处理:添加音频文件不存在的判断,输出更清晰的错误信息。
- 设置循环播放:将
player.numberOfLoops设为-1,让警示音持续播放直到速度下降。
额外注意事项
- 确认
yavas.mp3已添加到项目中,且在Target Membership中勾选了当前项目。 CLLocation.speed的单位是米/秒,7m/s相当于约25km/h。如果需要用公里/小时作为阈值,可将速度转换为:let currentSpeed = Int(sonKonum.speed * 3.6)。- 确保
Info.plist中添加了NSLocationWhenInUseUsageDescription权限描述,否则无法获取位置信息。
内容的提问来源于stack exchange,提问作者Yavuz Ulgar
相关产品推荐
相关产品推荐

