2017-02-03 15 views
2

아이폰에서 AVPlayer를 사용하여 오디오 파일을 재생하고 싶습니다. 오디오 파일은 장치의 로컬 저장소에있는 mp3 파일입니다. 외부 시간 원본과 동기화해야합니다 (재생 된 파일). 이 시간 소스는 재생 중에 바뀔 수 있으므로 때때로 동기화가 필요합니다. 나는 재생 오디오 파일의 시간을 변경하려면 다음 코드를 사용 :avplayer seek이 오디오 파일의 잘못된 위치에서 재생됩니다.

player.play() 

//sth here...... 


//the code which is executed periodically whene it is time to synchronize 
let currentShowTime = ...... //time in miliseconds 
print("current show time \(currentShowTime)") 
let timescale = player.currentItem!.asset.duration.timescale 
let currentTime = CMTime(value:Int64(Float64(currentShowTime!) * Float64(timescale)/1000.0), timescale:timescale) 

//alternative way I count the seek time but the effect is the same 
//let currentTime = CMTimeMakeWithSeconds(Float64(currentShowTime!)/1000.0, 1000) 

print("currenttime \(currentTime)") 
player!.seek(to: currentTime,toleranceBefore:kCMTimeZero, toleranceAfter:kCMTimeZero){done in 
    print("done: \(done)")               
    print("player currenttime \(self.player!.currentItem!.currentTime().seconds)") 
} 

문제는 오디오 파일이 잘못된 장소를 재생하는 것입니다. 모든 매개 변수 : 현재 쇼 시간, 현재 시간 및 플레이어 현재 시간은 동일합니다 (동일한 값을 인쇄하십시오). 그러나 나는 소리가 바뀌 었다고 들었다. 파일의 시작 부분을 재생할 때 이동은 작습니다 (500 밀리 초). 그러나 끝 부분 (파일의 20 분)은 이동이 훨씬 큽니다 (약 8 초). 나는 또한 작은 mp3 파일 (적은 비트 전송률로)을 제공 할 때 시프트가 더 작지만 파일의 품질이 좋을 때 시프트는 최대 20 초임을 알았다. 잘못 했나요? 아니면 AV 플레이어의 버그입니까?

답변

1

사용중인 파일이 VBR (가변 비트 전송률) mp3 파일이라고 가정합니다. 그것은

averageBitRate = totalBytes/duration 
offset = seekTime * averageBitRate 

를 사용하지만 VBR의 averageBitRate 파일에 걸쳐 일정하지 않은 파일, 그래서 offset이 잘못 계산 될 수있다 - AVFoundation은 VBR 파일을 통해 추구에 문제가 있습니다.

고정 비트 전송률로 mp3를 다시 인코딩해야합니다.

+1

고맙습니다! 그게 다야! – user7509906