HysteriaPlayer icon indicating copy to clipboard operation
HysteriaPlayer copied to clipboard

To Save Song in Document Directory

Open shaikshabana opened this issue 10 years ago • 7 comments

Hi , How to store Cached song in Document Directory. Thanks, Shabana

shaikshabana avatar Apr 07 '14 08:04 shaikshabana

I too am interested in this.

JacobSyndeo avatar Apr 07 '14 08:04 JacobSyndeo

I also want this feature. But it seems not possible? See the following links if they can help: http://lists.apple.com/archives/coreaudio-api/2013/Aug/msg00020.html http://stackoverflow.com/questions/6259095/caching-with-avplayer-and-avassetexportsession

windhood avatar May 05 '14 06:05 windhood

i got this work with a little research.here is my code.

+ (void)p_cacheAVPlayerItem:(AVPlayerItem *)avPlayerItem filePath:(NSString *)filePath {

    AVMutableComposition *composition = [AVMutableComposition composition];
    CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, avPlayerItem.asset.duration);
    AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    [compositionAudioTrack insertTimeRange:timeRange ofTrack:[[avPlayerItem.asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil];

    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetAppleM4A];
    exportSession.outputFileType = AVFileTypeAppleM4A;
    NSURL *outputURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@.m4a", filePath]];
    exportSession.outputURL = outputURL;
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
        switch(exportSession.status){
            case AVAssetExportSessionStatusExporting:
                NSLog(@"Exporting...");
                break;
            case AVAssetExportSessionStatusCompleted:
                NSLog(@"Export completed, wohooo!!");
                break;
            case AVAssetExportSessionStatusWaiting:
                NSLog(@"Waiting...");
                break;
            case AVAssetExportSessionStatusFailed:
                NSLog(@"Failed with error: %@", exportSession.error);
                break;
            default:
                NSLog(@"dont know what happened.");
                break;
        }
    }];
}

iBenjamin avatar Jun 29 '15 08:06 iBenjamin

Huh. If that works, it's a much less roundabout way than how I managed to implement it. I switch the protocol from https:// to a custom one, and set one of my objects as a handler for that URL type. After switching out the AVPlayerItems' URLs to use this protocol instead of https://, it then can sit BELOW AVFoundation and intercept all the data it's loading, building files with that data.

JacobSyndeo avatar Sep 08 '15 15:09 JacobSyndeo

@iBenjamin great work, been looking for something like that for a long time. I initially used what @JacobSyndeo did, it works but is not pretty.

I am seeing one issue though. It seems like the file that is saved is missing some parts, the music skips. Did you get that issue as well? If yes, how did you go about fixing this? If no, any ideas what might be causing this? Once again, great work figuring that out and thanks for your help in advance.

jaischeema avatar Jan 12 '16 20:01 jaischeema

@iBenjamin Any update on @jaischeema 's issue?

kevinlin505 avatar Feb 06 '16 15:02 kevinlin505

@kevinlin505 I encountered that issue as well. I worked around it by only caching the file if it exactly matched the byte size of the original on the server. (My server tells this to my app in advance.) I plan to migrate this to a true checksum system eventually, but I haven't had any issues with the byte count check.

JacobSyndeo avatar Apr 16 '16 01:04 JacobSyndeo