2016-08-26 2 views
2

averagePowerForChannelAVPlayer에 어떻게하면 내 음악 앱에서 오디오 시각화를 만들 수 있습니까? 이미 시각화 부분을 완료했지만 엔진 (실시간 볼륨 채널)에 붙어 있습니다.AVPlayer에서 averagePowerForChannel 받기

나는 .meteringEnabled 속성을 사용하여 쉽게 수행 할 수 있지만 어떤 알려진 이유 때문에 AVPlayer은 내 앱에 필수 항목임을 알고 있습니다. 실제로 AVAudioPlayer을 사용하려고 생각하고 있습니다. AVPlayer과 함께 원하는 결과를 얻지 만, 어색한 해결 방법이있는 것 같습니다. 어떻게 성능과 안정성에 영향을 미칠 수 있습니까? 미리 감사하십시오

+0

AVPlayer에 averagePowerForChannel을 가져 오는 방법을 찾았습니까? –

+0

안녕하세요, 솔루션을 찾았지만 비 온라인 파일을 재생할 때만 작동합니다. 필요하면 알려주세요 –

+0

불행히도 원격 파일을 사용하고 있습니다. 그래도 나는 당신의 솔루션에 관심이 있습니다. –

답변

-2

오디오 샘플을 시각화하고 오디오 데이터에 Core Audio 오디오 유닛 효과 (대역 통과 필터)를 적용하려면 AV Foundation과 함께 오디오 프로세서 클래스가 필요합니다. 당신은 찾을 수 본질적으로 sample by Apple here

당신은 아래와 같은 AVPlayer를에 당신이 관찰자를 추가해야합니다 : 여기

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { 
    if (object === videoPlayer.currentItem && keyPath == "tracks"){ 
     if let playerItem: AVPlayerItem = videoPlayer.currentItem { 
      if let tracks = playerItem.asset.tracks as? [AVAssetTrack] { 
       tapProcessor = MYAudioTapProcessor(AVPlayerItem: playerItem) 
       playerItem.audioMix = tapProcessor.audioMix 
       tapProcessor.delegate = self 
      } 
     } 
    } 
} 

가있다 :

// Notifications 
let playerItem: AVPlayerItem! = videoPlayer.currentItem 
playerItem.addObserver(self, forKeyPath: "tracks", options: NSKeyValueObservingOptions.New, context: nil); 

NSNotificationCenter.defaultCenter().addObserverForName(AVPlayerItemDidPlayToEndTimeNotification, object: videoPlayer.currentItem, queue: NSOperationQueue.mainQueue(), usingBlock: { (notif: NSNotification) -> Void in 
    self.videoPlayer.seekToTime(kCMTimeZero) 
    self.videoPlayer.play() 
    print("replay") 
}) 

그런 다음 아래의 오버라이드 (override) 방법으로 통지를 처리 sample project on GitHub

+0

테스트를 마친/작동중인 솔루션을 제공하십시오. ive는 avplayer를 사용하고 싶다고 말했습니다! 통해 단서 남자! –

+0

은 신속하게! –

+0

안녕하세요. 답장을 보내 주셔서 감사합니다. AVAudioPlayer를 사용하지 않을 계획인데, 실제 도전 과제는 이러한 종류의 AVPlayer를 사용하는 방법을 찾는 것입니다 !! 미안하지만 어떤 보상도받지 못한다!왜냐하면 필자는 이미 AVAudioPlayer에서 어떻게하는지 알았 기 때문입니다. 추신 : 당신은 AVAudioPlayer를 사용하고 있습니다 –

2

약 2 년간 AVPlayer 시각화 문제가 있습니다. 제 경우에는 HLS 라이브 스트리밍이 포함됩니다.이 경우, 제 지식에 따라 실행되지 않을 것입니다.

EDIT 이렇게하면 averagePowerForChannel: 방법에 액세스 할 수 없지만 원시 데이터에 액세스 할 수 있으며 예를 들어 FFT로 원하는 정보를 얻을 수 있습니다.

로컬 재생으로 작업하게되었습니다. 당신은 기본적으로 플레이어 플레이어 아이템이 궤도를 올리고 작동 할 때까지 기다립니다. 이 때 MTAudioProcessingTap을 오디오 믹스에 패치해야합니다.

처리 탭은 필요에 따라 원시 오디오 데이터를 계산할 수 있도록 지정한 콜백을 실행합니다. 여기

는 (비록 ObjC에 부풀어 오르고 죄송합니다) 빠른 예입니다

#import <AVFoundation/AVFoundation.h> 
#import <MediaToolbox/MediaToolbox.h> 

void init(MTAudioProcessingTapRef tap, void *clientInfo, void **tapStorageOut) {}; 
void finalize(MTAudioProcessingTapRef tap) {}; 
void prepare(MTAudioProcessingTapRef tap, CMItemCount maxFrames, const AudioStreamBasicDescription *processingFormat) {}; 
void unprepare(MTAudioProcessingTapRef tap) {}; 
void process(MTAudioProcessingTapRef tap, CMItemCount numberFrames, MTAudioProcessingTapFlags flags, AudioBufferList *bufferListInOut, CMItemCount *numberFramesOut, MTAudioProcessingTapFlags *flagsOut) {}; 

- (void)play { 
    // player and item setup ... 

    [[[self player] currentItem] addObserver:self forKeyPath:@"tracks" options:kNilOptions context:NULL]; 
} 

////////////////////////////////////////////////////// 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)changecontext:(void *)context 
    if ([keyPath isEqualToString:@"tracks"] && [[object tracks] count] > 0) { 
     for (AVPlayerItemTrack *itemTrack in [object tracks]) { 
      AVAssetTrack *track = [itemTrack assetTrack]; 

      if ([[track mediaType] isEqualToString:AVMediaTypeAudio]) { 
       [self addAudioProcessingTap:track]; 
       break; 
      } 
     } 
} 

- (void)addAudioProcessingTap:(AVAssetTrack *)track { 
    MTAudioProcessingTapRef tap; 
    MTAudioProcessingTapCallbacks callbacks; 
    callbacks.version = kMTAudioProcessingTapCallbacksVersion_0; 
    callbacks.clientInfo = (__bridge void *)(self); 
    callbacks.init = init; 
    callbacks.prepare = prepare; 
    callbacks.process = process; 
    callbacks.unprepare = unprepare; 
    callbacks.finalize = finalise; 

    OSStatus err = MTAudioProcessingTapCreate(kCFAllocatorDefault, &callbacks, kMTAudioProcessingTapCreationFlag_PostEffects, &tap); 

    if (err) { 
     NSLog(@"error: %@", [NSError errorWithDomain:NSOSStatusErrorDomain code:err userInfo:nil]); 
     return; 
    } 

    AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix]; 

    AVMutableAudioMixInputParameters *inputParams = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:audioTrack]; 
    [inputParams setAudioTapProcessor:tap]; 
    [audioMix setInputParameters:@[inputParams]]; 

    [[[self player] currentItem] setAudioMix:audioMix]; 
} 

이 논의는 2 년 전부터 my question에 걸쳐 진행되므로으로 확인해야합니다 있습니다 잘.

+0

감사합니다, objective-c도 좋습니다. 해결책을 찾을 때 이전 게시물을 찾았습니다! 유일한 문제는 HLS 라이브 스트리밍을 사용하지 않는 것입니다. 그것 전부에 관하여 * .audio (mp3/wav/etc ..) 파일! im은 파일을 캐시하고 mp3 파일로 저장 한 다음 시각화를 업데이트하는 솔루션에서 작업합니다. 코드를 테스트하고 도움이되는지 확인하십시오. –

+0

내 물건이 스트리밍 *으로 작동하지 않기 때문에 괜찮습니다. 그러나 로컬 파일 (당신이 요청한 것)으로 작동합니다. 또한 내 편집 내용을 확인하고 코드에 더 많은 정보를 추가했습니다! –

+0

ok 아프다. 내 프로젝트에서 테스트 할 수 있다면 되돌아 간다. –

관련 문제