اطلاعیه

Collapse
هیچ اطلاعیه ای هنوز ایجاد نشده است .

آموزش دانلود فایل و پخش آهنگ

Collapse
X
 
  • فیلتر
  • زمان
  • نمایش
پاک کردن همه
new posts

  • آموزش دانلود فایل و پخش آهنگ

    یکی از دوستان توی سایت x-code درخواست کرده بود که آموزش دانلود فایل و پخش موزیک را بذارم.البته بصورت stream میخواستن اما گفتن اول دانلود و بعد play هم فعلا باشه بد نیست).

    محتوای مخفی - انجمن تخصصی آیفون

    محتوای مخفی - انجمن تخصصی آیفون

    خوب همونطور که می بینید برنامه شامل ۲ قسمت هست
    ۱ - دانلود فایل
    ۲ - پخش اون
    ابتدا یک تابع ایجاد میکنیم به نام fileDownloader که یک پارامتر به نام NSURL را میگیره
    کد:
    - (void) fileDownloder:(NSURL*) url
    {
    }
    خوب برای دانلود فایل ابتدا باید یک Object از جنس NSData بسازیم که محتویات دانلودی را درونش بریزیم.

    کد:
     NSData *myData = [NSData dataWithContentsOfURL:url];
    کد بالا مسیر فایل داده شده را دانلود میکنه و داخل myData میریزه ( دقیقا به همه راحتی )

    خوب فایل که دانولد شد باید اون را یکجا ذخیره کنیم! خوب حتما میدونید که شما نمیتونید هرجا که دلتون خواست فایل را ذخیره کنید ( اگر اینکارو بکنید توی AppStore چی میشید ؟ بله Reject )
    شما محدوده دسترسی که دارید داخل فولدر Application مربوط به خودتون هست.
    پس ما باید مسیر ذخیره شده Application را بدست بیاریم توسط کد زیر.
    کد:
    NSArray *myPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        
        NSString *absolutePath = [myPath objectAtIndex:0];
    حالا میخواهیم فایلی را که دانلود کردیم را به نام دلخواه ذخیره کنیم!

    کد:
        NSString *savePath = [NSString stringWithFormat:@"%@/mySong.mp3" , absolutePath];
    تا الان کارهایی که کردیم این بوده! فایل دانلود شده! مسیر و نام مورد نظر را ساختیم و آماده شده برای ذخیره شدن بصورت فایل! (تا الان همه چی داخل متغییر ها بوده ).


    کد:
        [myData writeToFile:savePath atomically:YES];
    واقعا xcode و objective-c قابلیت های منحصر به فردی را گذاشتن! باورتون میشه به همین راحتی که download Manager شخصی برای خودمون نوشتیم.

    حالا فایل ذخیره شده! باید اون را پخش کنیم که من اینجا توسط AVFoundation اینکارو میکنم.

    اول از همه AVFoundation Framework را به پروژه اضافه کنید و بعد داخل فایل .h فایل header را اضافه میکنیم

    کد:
    #import <AVFoundation/AVFoundation.h>
    و بعد به پروژمون Delegate مربوط به AVFoundation را اضافه میکنیم

    کد:
    @interface ViewController : UIViewController < AVAudioPlayerDelegate>
    حالا یا توی فایل .h یا داخل .m بصورت یک Property برای AVAudioPlayer میسازیم

    کد:
    @property ( nonatomic , strong ) AVAudioPlayer *myAP;
    و بعد اون را توی فایل .m ؟؟
    بله Syntesize میکنیم

    کد:
    @synthesize myAP;
    حالا توی ViewDidLoad باید به myAP که Player ما هست Delegate را self بدیم.

    کد:
          myAP.delegate = self;
    حالا برای پخش فایل مربوط یک تابع درست میکنیم به نام play
    کد:
    -(void) play
    {
        
        NSArray *myPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        
        NSString *absolutePath = [myPath objectAtIndex:0];
        
        NSString *savePath = [NSString stringWithFormat:@"%@/mySong.mp3" , absolutePath];
        
       
        
        NSURL *mpUrl = [NSURL fileURLWithPath:savePath];
        
       myAP = [[AVAudioPlayer alloc] initWithContentsOfURL:mpUrl error:nil];
      
        
        [myAP play];
      
    }

    کد بالا مثل FileDownload هست تا حدی فقط دیگه داخل فایلی دانلود نمیشه اما طرز بدست آوردن مسیر همونطور هست و طرز ساختن یک Object از جنس AVAudioPlayer . و دادن مسیر بصورت NSURL .

    حالا باید توی ViewDidLoad به ترتیب صدا بزنیم.

    کد:
    - (void)viewDidLoad
    {
        [super viewDidLoad];
          myAP.delegate = self;
        [self fileDownloder:[NSURL  URLWithString:@"http://site.com/music.mp3"]];
        [self play];
        
        
    }
    اول فایل دانلود شده و بعد پخش میشه! شما میتونید یک Button تعریف کنید و تابع play را اونجا صدا بزنید.

    سوالی بود همینجا بپرسید.

    محتوای مخفی - انجمن تخصصی آیفون


    کل کد بصورت یکجا :
    کد:
    - (void)viewDidLoad
    {
        [super viewDidLoad];
          myAP.delegate = self;
        [self fileDownloder:[NSURL  URLWithString:@"http://site.com/music.mp3"]];
        [self play];
        
        
    }
    
    
    - (void) fileDownloder:(NSURL*) url
    {
        
        NSData *myData = [NSData dataWithContentsOfURL:url];
        
        NSArray *myPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        
        NSString *absolutePath = [myPath objectAtIndex:0];
        
        NSString *savePath = [NSString stringWithFormat:@"%@/mySong.mp3" , absolutePath];
        
        [myData writeToFile:savePath atomically:YES];
    }
    
    -(void) play
    {
        
        NSArray *myPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        
        NSString *absolutePath = [myPath objectAtIndex:0];
        
        NSString *savePath = [NSString stringWithFormat:@"%@/mySong.mp3" , absolutePath];
        
       
        
        NSURL *mpUrl = [NSURL fileURLWithPath:savePath];
        
       myAP = [[AVAudioPlayer alloc] initWithContentsOfURL:mpUrl error:nil];
      
        
        [myAP play];
      
    }
    ویرایش توسط E H S A N : https://i-phone.ir/forums/member/37262-e-h-s-a-n در ساعت 24-07-2012, 07:33 PM
    " MICROSOFT'S MONSTER OF SOFTWARE, APPLE'S MONSTER OF HARDWARE "
    TECHNOLOGY NEEDS BOTH OF THEM

  • #2
    من حدود سه روزه که با یه مشکلی مواجهم و هنوز نتونستم هیچ جوره حلش بکنم. گفتم اینجا بپرسم شاید کسی بتونه کمکم کنه.

    برنامه من یه برنامه ساده مبتنی بر نویگیشن هست با MasterViewController و DetailViewController. تو اولی که table view هست، لیست فایل های صوتیم رو دارم و با انتخاب هرکدوم از سطرهای جدول، وارد وی-یو کنترلر دومی می‌شم که یه سری توضیح در مورد فایل داره و همینطور صدا رو پخش می‌کنه.
    مشکل اینجاست که وقتی یک فایل صوتی رو با زدن دکمه پلی، پخش می‌کنم و بعد به صفحه اصلی برمیگردم و یه سطر دیگه از جدول رو انتخاب می کنم، فایل دوم رو که میخوام پلی کنم، فایل اولی همچنان در حال پخش هست و دوتا فایل رو هم اجرا می‌شن.
    مشکل اینجاست که پلیر همیشه نیل تصور میشه و در نتیجه فایل قبلیش رو استاپ نمی‌کنه. ممنون می شم اگه بتونین کمک کنین.

    در هدر MasterViewController:
    کد:
    @property (nonatomic, strong) AVAudioPlayer *audioPlayer;
    در فایل اصلی MasterViewController:
    کد:
    @synthesize audioPlayer;
    
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if ([[segue identifier] isEqualToString:@"showDetail"])
        {
            NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
            NIKDetailViewController *detailViewController = (NIKDetailViewController *) segue.destinationViewController;
            [detailViewController setAudioPlayer:audioPlayer];
    
            [detailViewController setFeedEntry:[[[self feedParser] feedItems] objectAtIndex:indexPath.row]];
    
        } else {
            NSLog(@"Segue Identifier: %@", segue.identifier);
        }
    
    }

    در هدر DetailViewController:
    کد:
    @property (nonatomic, strong) AVAudioPlayer *audioPlayer;
    در بدنه اصلی:
    موضوع اینجاست که audioPlayer همیشه نیل هست و درنتیجه هیچ وقت دستور استاپ اجرا نمی شه.

    کد:
    @synthesize audioPlayer;
    
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Custom initialization
            selectedItem = [[NSString alloc]init];
        }
        return self;
    }
    
    
    #pragma mark - Managing the Audio Playback
    
    
    - (IBAction)togglePlayingState:(id)button
    {
        //Handle the button pressing
        [self togglePlayPause];
    }
    
    
    
    - (void)playAudio
    {
        //Play the audio and set the button to represent the audio is playing
        [audioPlayer play];
        [playPauseButton setImage:[UIImage imageNamed:@"player_pause"] forState:UIControlStateNormal];
    }
    
    - (void)pauseAudio
    {
        //Pause the audio and set the button to represent the audio is paused
        [audioPlayer pause];
        [playPauseButton setImage:[UIImage imageNamed:@"player_play"] forState:UIControlStateNormal];
    
    }
    
    - (void)togglePlayPause
    {
        //Toggle if the music is playing or paused
        if (!audioPlayer.playing)
        {
            [self playAudio];
        }
        else if (audioPlayer.playing)
        {
            [self pauseAudio];
        }
    }
    
    
    - (void)streamAudio
    {   
        currentFileName = [[feedEntry podcastDownloadURL] lastPathComponent];
    
        NSString* documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString* path = [documentPath stringByAppendingPathComponent:currentFileName];
        NSURL* audioURL = [NSURL fileURLWithPath: path];
    
        if (audioPlayer != nil)
        {
            if (audioPlayer.isPlaying)
            {
                [audioPlayer stop];  //THIS IS NEVER CALLED
            }
            audioPlayer = nil;           //THIS IS NEVER CALLED
        }
    
        audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:nil];
    
        // Set a timer which keep getting the current music time and update the UISlider in 1 sec interval
        playbackTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateSlider) userInfo:nil repeats:YES];
        // Set the maximum value of the UISlider
        seekSlider.maximumValue = audioPlayer.duration;
    
    
        currentTime.text = [NSString stringWithFormat:@"%d:%02d", (int)audioPlayer.currentTime / 60, (int)audioPlayer.currentTime % 60, nil];
        remainingTime.text = [NSString stringWithFormat:@"%d:%02d", (int)(audioPlayer.duration - audioPlayer.currentTime) / 60, (int)(audioPlayer.duration - audioPlayer.currentTime) % 60, nil];
    
        // Set the valueChanged target
        [seekSlider addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged];
        audioPlayer.delegate = self;
        [audioPlayer prepareToPlay]; //Add the audio to the memory.
    }
    
    
    - (void)updateSlider
    {
        // Update the slider about the music time
        seekSlider.value = audioPlayer.currentTime;
    }
    
    - (IBAction)sliderChanged:(UISlider *)sender {
        // Fast skip the music when user scrolls the slider
        [audioPlayer stop];
        [audioPlayer setCurrentTime:seekSlider.value];
        audioPlayer.delegate = self;
    
        [audioPlayer prepareToPlay];
        [audioPlayer play];
    }
    
    // Stop the timer when the music is finished (Need to implement the AVAudioPlayerDelegate in the Controller header)
    - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
        // Music completed
        if (flag) {
            [playbackTimer invalidate];
        }
    }
    
    
    //Make sure we can recieve remote control events
    - (BOOL)canBecomeFirstResponder {
        return YES;
    }
    
    - (void)remoteControlReceivedWithEvent:(UIEvent *)event {
        //if it is a remote control event handle it correctly
        if (event.type == UIEventTypeRemoteControl) {
            if (event.subtype == UIEventSubtypeRemoteControlPlay) {
                [self playAudio];
            } else if (event.subtype == UIEventSubtypeRemoteControlPause) {
                [self pauseAudio];
            } else if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause) {
                [self togglePlayPause];
            }
        }
    }
    
    #pragma mark - view life cycle
    
    
    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
    
        //Once the view has loaded then we can register to begin recieving controls and we can become the first responder
        [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
        [self becomeFirstResponder];
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
    
        //End recieving events
        [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
        [self resignFirstResponder];
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    
        [self streamAudio];
    
        //Make sure the system follows our playback status - to support the playback when the app enters the background mode.
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
        [[AVAudioSession sharedInstance] setActive: YES error: nil];
    
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    @end

    نظر

    صبر کنید ..
    X