2013-07-16 3 views
1

사용자의 소리를 녹음하고 다시 재생하는 음성 메모 앱을 만들고 있습니다.UISlider의 사용자 지정 위치에서 오디오를 재생하는 방법?

녹음 부분이 정상적으로 작동합니다. 녹음 된 파일은 사용자가 파일을 재생하기 시작한 저장된 파일을 탭할 때 &에 성공적으로 저장되었습니다.

나는 재생 진행을 나타 내기 위해 UISlider을 사용하고 있습니다. 이제 UISlideruserInteractionEnabled 속성을 NO으로 비활성화했습니다. 따라서 사용자가 UISlider 바와 상호 작용하도록 허용하지 않습니다.

무엇이 필요한가요,이 속성을 YES으로 설정하면 원하는 오디오 재생 위치를 선택할 수 있습니다. 이를 위해 슬라이더 코드에 다음 줄을 추가했습니다.

[mySlider addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged]; 

위의 행을 추가하면 슬라이더 위치가 sliderChanged: 메쏘드 안에 있습니다. 그러나, 나는 선택한 위치에서 플레이어를 시작하는 방법을 모른다. 각 파일에는 다양한 크기가 있으므로 재생 시간도 다릅니다.

샘플 코드가 있습니까? 당신의 도움이 필요합니다.

감사합니다.

답변

0

AVAudioPlayer에는 설정할 수있는 currentTime 속성이 있습니다. AVAudioPlayer 설명서를 참조하십시오.

3

당신은 사운드 파일의 재생 슬라이더 분을로드하고 최대는 방법

yourSlider.minValue = 0.0; 
yourSlider.maxValue = player.duration; 

값 전에 sliderChanged:

player.currentTime = yourSlider.value; 
1

다음 코드 샘플은 시작한다. 그러면 슬라이더가 진행 표시기로 작동하여 사용자가 지정한 위치에서 재생을 시작하도록 스크러빙 할 수 있습니다.

/* SliderMoved가 슬라이더 값이 변했 때 호출 중 하나가 자동차 오디오 재생으로 업데이트 될 때 사용자 스크럽은 또는 진행시 */

-(void)sliderMoved:(id)sender 
{ 
    [self.playbackTimer invalidate]; 
    self.playbackTimer = nil; 
    NSInteger position = (NSInteger)self.slider.value * 60; // Assume the slider scale is in minutes- so convert to sec 
    if (self.isPlaying) 
    { 
     [self.audioPlayer pause]; 
    } 
    [self.audioPlayer setCurrentTime:position]; 
    if (self.isPlaying) 
    { 
     [self startOrResumePlaying]; 
    } 
    [self updateSlider]; 

} 

/* updateSlider 슬라이더 값을 업데이트하는 도우미 함수입니다 */

-(void)updateSlider 
{ 
    float total= self.audioPlayer.duration; 
    float f = (self.audioPlayer.currentTime) ; 
    self.slider.value = f/60.0; 


    self.progressLabel.text = [NSString stringWithFormat:@"%.2f",self.slider.value]; 

} 

/* startOrResumePlaying 오디오 재생을 시작하고 자동 진행 표시기를 증가 타이머를 초기화 매 3 초 */

-(void)startOrResumePlaying 
{ 

    [self.audioPlayer prepareToPlay]; 
    [self.audioPlayer play]; 
    self.isPlaying = YES; 
    self.playbackTimer=[NSTimer scheduledTimerWithTimeInterval:3.0 
                 target:self 
                 selector:@selector(handleTimer:) 
                 userInfo:nil 
                 repeats:YES]; 
    [[NSRunLoop currentRunLoop] addTimer:self.playbackTimer forMode:NSDefaultRunLoopMode]; 

} 
1

광산은 rajagp와 Igor Bidiniuc의 답변을 결합하여 작동하므로 두 가지 모두에 투표하겠습니다.

#import <AVFoundation/AVFoundation.h> 

@property (nonatomic, strong) IBOutlet UIButton *playButton; 
@property (nonatomic, strong) IBOutlet UISlider *slider; 
@property (nonatomic, strong) IBOutlet UILabel *timeLabel; 
@property (nonatomic, strong) AVAudioPlayer *audioPlayer; 
@property (nonatomic, strong) NSTimer *timer; 

- (IBAction)playPause:(id)sender; 
- (IBAction)sliderValueChanged:(id)sender; 

여기 구현 파일이 있습니다.

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 
    self.slider.continuous = YES; 
    NSError *error = nil; 
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error]; 
    if (error == nil) { 
     NSLog(@"audio session initialized successfully"); 
     [self PlayAudio:@"fileName"]; 
    } else { 
     NSLog(@"error initializing audio session: %@", [error description]); 
    } 
} 

- (void)PlayAudio:(NSString*)file { 
    NSError *error = nil; 
    NSString *soundPath =[[NSBundle mainBundle] pathForResource:file ofType:@"mp3"]; 
    NSURL *fileURL = [NSURL fileURLWithPath:soundPath]; 

    if ([self.audioPlayer isPlaying]) { 
     [self.audioPlayer pause]; 
     [self.timer invalidate]; 
    } 
    self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error]; 
    self.audioPlayer.delegate = self; 

    if (error == nil) { 
     NSLog(@"audio player initialized successfully"); 

     [self playPause:nil]; 

    } else { 
     NSLog(@"error initializing audio player: %@", [error description]); 
    } 
} 



- (void)viewWillDisappear:(BOOL)animated { 
    if ([self.audioPlayer isPlaying]) { 
     [self.audioPlayer pause]; 
     [self.timer invalidate]; 
    } 

    [super viewWillDisappear:animated]; 
} 

-(IBAction)playPause:(id)sender 
{ 
    if ([self.audioPlayer isPlaying]) { 
     [self.audioPlayer pause]; 
     self.playButton.imageView.image = [UIImage imageNamed:@"play"]; 
     [self.timer invalidate]; 

    } else { 
     [self.audioPlayer play]; 
     self.playButton.imageView.image = [UIImage imageNamed:@"pause"]; 

     self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateProgress) userInfo:nil repeats:YES]; 
    } 

} 

- (IBAction)sliderValueChanged:(id)sender { 

    [self.timer invalidate]; 
    self.timer = nil; 
    float position = self.slider.value; 

    if (self.audioPlayer.isPlaying) 
    { 
     [self playPause:nil]; 
    } 
    [self.audioPlayer setCurrentTime:position]; 
    if (self.audioPlayer.isPlaying) 
    { 
     [self playPause:nil]; 
    } 
    [self updateProgress]; 
} 

#pragma mark - Timer delegate 

-(void)updateProgress 
{ 
    NSInteger durationMinutes = [self.audioPlayer duration]/60; 
    NSInteger durationSeconds = [self.audioPlayer duration] - durationMinutes * 60; 

    NSInteger currentTimeMinutes = [self.audioPlayer currentTime]/60; 
    NSInteger currentTimeSeconds = [self.audioPlayer currentTime] - currentTimeMinutes * 60; 
    NSString *progressString = [NSString stringWithFormat:@"%d:%02d/%d:%02d", currentTimeMinutes, currentTimeSeconds, durationMinutes, durationSeconds]; 
    self.timeLabel.text = progressString; 

    self.slider.minimumValue = 0.0; 
    self.slider.maximumValue = [self.audioPlayer duration]; 

    [self.slider setValue:[self.audioPlayer currentTime] animated:YES]; 
} 

#pragma mark - AVAudioPlayer delegate methods 

-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag 
{ 
    if (flag) { 
     self.playButton.imageView.image = [UIImage imageNamed:@"play"]; 
     [self.timer invalidate]; 
    } 
} 
4

스위프트에서 솔루션 공유.

zeeran이 게시 한 objective-c 구현을 기반으로 슬라이더를 사용하여 프로젝트를 수행 할 수 있었고, 이전에 수행했던 현재 시간을 계속 업데이트합니다. 나는 너무 기뻐.

그래서 누군가에게 도움이 될 수 있도록 신속한 구현을 공유하고 싶습니다.

import UIKit 
import AVFoundation 
import Foundation 

class ActivityViewController: UIViewController, AVAudioPlayerDelegate { 
    /// The player & sound file object 
    var audioPlayer = AVAudioPlayer() 
    var activitySound = NSURL() 

    var updater : CADisplayLink! = nil // tracks the time into the track 
    var updater_running : Bool = false // did the updater start? 
    var playing : Bool = false //indicates if track was started playing 

    @IBOutlet var playButton: UIButton! 
    @IBOutlet var timeLabel: UILabel! // shows time and duration 
    @IBOutlet var audioSlider: UISlider! // slider object 

    @IBAction func pressedPlayButton(sender: AnyObject) { 
     if (playing == false) { 
      updater = CADisplayLink(target: self, selector: Selector("updateProgress")) 
      updater.frameInterval = 1 
      updater.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) 
      updater_running = true 
      audioPlayer.play() 
      playButton.selected = true // pause image is assigned to "selected" 
      playing = true 
      updateProgress() 
     } else { 
      updateProgress() // update track time 
      audioPlayer.pause() // then pause 
      playButton.selected = false // show play image (unselected button) 
      playing = false // note track has stopped playing 
     } 
    } 

    // action for when the slider is moved: set as 'valuechanged' for UISlider object 
    @IBAction func sliderMoved(sender: UISlider) { 
     // if the track was playing store true, so we can restart playing after changing the track position 
     var wasPlaying : Bool = false 
     if playing == true { 
      audioPlayer.pause() 
      wasPlaying = true 
     } 
     audioPlayer.currentTime = NSTimeInterval(round(audioSlider.value)) 
     updateProgress() 
     // starts playing track again it it had been playing 
     if (wasPlaying == true) { 
      audioPlayer.play() 
      wasPlaying == false 
     } 
    } 

    // Timer delegate method that updates current time display in minutes 
    func updateProgress() { 
     let total = Float(audioPlayer.duration/60) 
     let current_time = Float(audioPlayer.currentTime/60) 
     audioSlider.minimumValue = 0.0 
     audioSlider.maximumValue = Float(audioPlayer.duration) 
     audioSlider.setValue(Float(audioPlayer.currentTime), animated: true) 
     timeLabel.text = NSString(format: "%.2f/%.2f", current_time, total) as String 
    } 

    //- AVAudioPlayer delegate method - resets things when track finishe playing 
    func PlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool) { 
     if flag { 
      playButton.selected = false 
      playing = false 
      audioPlayer.currentTime = 0.0 
      updateProgress() 
      updater.invalidate() 
     } 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // configure AVAudioPlayer as audioPlayer object 
     let file = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("file1", ofType: "mp3")!)! 
     audioPlayer = audioPlayer(contentsOfURL: file, error: nil) 
     audioPlayer.delegate = self 

     audioSlider.continuous = false 
    } 

    // method makes sure updater gets stopped when leaving view controller, because otherwise it will run indefinitely in background 
    override func viewWillDisappear(animated: Bool) { 
     if playing == true { 
      audioPlayer.stop() 
     } 
     updater.invalidate() 
     updater_running = false 
     super.viewWillDisappear(animated) 
    } 
} 
관련 문제