Search code examples
iosobjective-cnsurlconnectionnsdataaac

NSData from NSURLConnection does not match when downloading file directly


I am trying to find FFF9 hex representation in and NSData object that I get with NSURLConnection when I type the url address to my web browser and download the file to my mac then I open it a text editor I get following values which seems true

Few lines from start:

4944 3304 0000 0000 025f 5449 5432 0000
0006 0000 0353 7479 6c65 5450 4531 0000
000e 0000 0354 6179 6c6f 7220 5377 6966
7400 5758 5858 0000 016e 0000 0055 524c
0073 6f6e 675f 7370 6f74 3d22 4d22 204d
6564 6961 4261 7365 4964 3d22 3230 3632
3435 3622 2069 7475 6e65 7354 7261 636b
4964 3d22 3022 2061 6d67 5472 6163 6b49
643d 222d 3122 2061 6d67 4172 7469 7374
4964 3d22 3022 2054 4149 443d 2233 3332
3231 2220 5450 4944 3d22 3239 3139 3533
3234 2220 6361 7274 6375 7449 643d 2230
3838 3030 3832 3030 3122 2061 6d67 4172
7477 6f72 6b55 524c 3d22 6874 7470 3a2f
2f61 7373 6574 732e 6968 6561 7274 2e63
6f6d 2f69 6d61 6765 732f 3130 3830 2f4d
4930 3030 3337 3936 3333 3622 206c 656e
6774 683d 2230 303a 3033 3a34 3722 2075
6e73 4944 3d22 2d31 2200 5052 4956 0000
0035 0000 636f 6d2e 6170 706c 652e 7374
7265 616d 696e 672e 7472 616e 7370 6f72
7453 7472 6561 6d54 696d 6573 7461 6d70
0000 0000 0084 e5fb 8eff f95c 4022 a000
0148 3614 56a8 4506 0b42 7230 602c 1419
9813 6c2d 7863 46ef 3805 6845 ded6 0387
9d24 4253 30ed 0210 5d45 1dd6 a660 8aa0
0063 5e6a 83a6 44ba 7136 154c 321e af45
a499 eb24 e389 a7ab 7184 79cc 3b10 61ff
d83c 95ff 22a2 1738 7236 1a30 0ccb 3996
772d b001 930f 5023 1e57 2bfb a9dd b80b
6f34 0441 3b06 ad59 0cf7 07a1 b151 710b

then when I get the data in Objective-c with nsurl I get the following data

few lines from nsdata

3c21444f 43545950 45206874 6d6c2050 55424c49 4320222d 2f2f5733 432f2f44 54442058 48544d4c 20312e31 2f2f454e 22202268 7474703a 2f2f7777 772e7733 2e6f7267 2f54522f 7868746d 6c31312f 4454442f 7868746d 6c31312e 64746422 3e0a0a3c 68746d6c 20786d6c 6e733d22 68747470 3a2f2f77 77772e77 332e6f72 672f3139 39392f78 68746d6c 2220786d 6c3a6c61 6e673d22 656e223e 0a202020 203c6865 61643e0a 20202020 20202020 3c746974 6c653e54 68652070 61676520 6973206e 6f742066 6f756e64 3c2f7469 746c653e 0a202020 20202020 203c6d65 74612068 7474702d 65717569 763d2243 6f6e7465 6e742d54 79706522 20636f6e 74656e74 3d227465 78742f68 746d6c3b 20636861 72736574 3d555446 2d382220 2f3e0a20 20202020 2020203c 7374796c 65207479 70653d22 74657874 2f637373 223e0a20 20202020 20202020 2020202f 2a3c215b 43444154 415b2a2f 0a202020 20202020 20202020 20626f64 79207b0a 20202020 20202020 20202020 20202020 6261636b 67726f75 6e642d63 6f6c6f72 3a202366 66663b0a 20202020 20202020 20202020 20202020 636f6c6f 723a2023 3030303b 0a202020 20202020 20202020 20202020 20666f6e 742d7369 7a653a20 302e3965 6d3b0a20 20202020 20202020 20202020 20202066 6f6e742d 66616d69 6c793a20 73616e73 2d736572 69662c68 656c7665 74696361 3b0a2020 20202020 20202020 20202020 20206d61 7267696e 3a20303b 0a202020 20202020 20202020 20202020 20706164 64696e67 3a20303b 0a202020 20202020 20202020 207d0a20 20202020 20202020 2020203a 6c696e6b 207b0a20 20202020 20202020 20202020 20202063 6f6c6f72 3a202363 30303b0a 20202020 20202020 20202020 7d0a2020 20202020 20202020 20203a76 69736974 6564207b 0a202020 20202020 20202020 20202020 20636f6c 6f723a20 23633030 3b0a2020 20202020 20202020 20207d0a 20202020 20202020 20202020 613a686f 76657220 7b0a2020 20202020 20202020 20202020 2020636f 6c6f723a 20236635 303b0a20 20202020 20202020 2020207d 0a202020 20202020 20202020 20683120 7b0a2020 20202020 20202020 20202020 20207465 78742d61 6c69676e 3a206365 6e746572 3b0a2020 20202020 20202020 20202020 20206d61 7267696e 3a20303b 0a202020 20202020 20202020 20202020 20706164 64696e67 3a20302e 36656d20 32656d20 302e3465 6d3b0a20 20202020 20202020 20202020 20202062 61636b67 726f756e 642d636f 6c6f723a 20233239 34313732 3b0a2020 

Which is obviously not the same.

When I run the following code on the file I downloaded via webbrowser it works

NSDate *start = [NSDate date];
// The magic start data object is only created once safely and
// then reused each time
static NSData* magicStartData = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    static const uint8_t magic[] = { 0xff, 0xf9 };
    magicStartData = [NSData dataWithBytesNoCopy:(void*)magic length:2 freeWhenDone:NO];
});

// assume data is the NSData with embedded data
NSLog(@"data %@",audioData);
NSData* subdata;
NSRange rangeCost = [audioData rangeOfData:magicStartData options:0 range:NSMakeRange(0, [audioData length])];
if (rangeCost.location != NSNotFound) {
    // This assumes the subdata doesn't have a specific range and is just everything
    // after the magic, otherwise adjust
    subdata = [audioData subdataWithRange:NSMakeRange(rangeCost.location, [audioData length] - rangeCost.location)];
    NSLog(@"Sub data %@",subdata);

    NSDate *methodFinish = [NSDate date];
    NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:start];
    NSLog(@"Execution Time: %f", executionTime);


}

Obviously same code cannot find FFF9 in NSData I get via NSURLConnection

My connection code;

 (void)downloadDataWithUrl:(NSURL *)url andFileName:(NSString *)fileName
{
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                               if ( !error )
                               {
                                      //NSLog(@"data %@",data);
                                   [self audioFileReaderWithData:data andFileName:fileName];

                               } else{
                                    NSLog(@"downloadDataWithUrl failed");
                               }
                           }];
}

Any idea whats going on and how can I solve this problem?

EDIT:::::::::
I feel like I need to explain exact story here.
I download following url first http://playlists.ihrhls.com/c5/1469/playlist.m3u8 Parsing that link gives a .m3u file link which something like this

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=49000,CODECS="mp4a.40.5"
http://playlists.ihrhls.com/c5/1469/playlist.m3u8?listeningSessionID=54868da4e3b93b4a_5943659_OcMl11nw_0000006Uz93&downloadSessionID=0

Downloading this http://playlists.ihrhls.com/c5/1469/playlist.m3u8?listeningSessionID=54868da4e3b93b4a_5943659_OcMl11nw_0000006Uz93&downloadSessionID=0

here it gives 3 chunks of .aac files.

#EXTM3U
#EXT-X-ALLOW-CACHE:NO

#EXT-X-TARGETDURATION:11
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10,title="Spotblockend",artist="Spotblockend",url="song_spot=\"O\" MediaBaseId=\"0\" itunesTrackId=\"0\" amgTrackId=\"-1\" amgArtistId=\"0\" TAID=\"0\" TPID=\"0\" cartcutId=\"1\" amgArtworkURL=\"\" length=\"00:00:00\" unsID=\"-1\""
http://chunks.ihrhls.com/1469/khHfMfxGiN5-241374-9984.aac
#EXTINF:10,title="Spotblockend",artist="Spotblockend",url="song_spot=\"O\" MediaBaseId=\"0\" itunesTrackId=\"0\" amgTrackId=\"-1\" amgArtistId=\"0\" TAID=\"0\" TPID=\"0\" cartcutId=\"1\" amgArtworkURL=\"\" length=\"00:00:00\" unsID=\"-1\""
http://chunks.ihrhls.com/1469/lvwjN9sH8Ke-241375-9984.aac
#EXTINF:10,title="Spotblockend",artist="Spotblockend",url="song_spot=\"O\" MediaBaseId=\"0\" itunesTrackId=\"0\" amgTrackId=\"-1\" amgArtistId=\"0\" TAID=\"0\" TPID=\"0\" cartcutId=\"1\" amgArtworkURL=\"\" length=\"00:00:00\" unsID=\"-1\""
http://chunks.ihrhls.com/1469/iE906eJEm2i-241376-10031.aac

and I need those .aac files in NSData format.

So as I explained in my question when I type http://chunks.ihrhls.com/1469/iE906eJEm2i-241376-10031.aac link in my web browser it sends me the actual .aac file but when I use same link with NSURL connection NSDATA response is an html page with The page is not found response.

Why is that happening!?

Note: that m3u file and .aac files expires every other two hours so by the time you read this those links wont be available, so you need to check this link again http://playlists.ihrhls.com/c5/1469/playlist.m3u8


Solution

  • Update from question additional information (again):

    Test code:

    NSURL *url;
    NSMutableURLRequest *request;
    NSURLResponse *response;
    NSError *error;
    NSData *data;
    NSString *string;
    NSRange range;
    
    // First get the current URL
    url = [NSURL URLWithString:@"http://playlists.ihrhls.com/c5/1469/playlist.m3u8"];
    request = [NSMutableURLRequest requestWithURL:url];
    data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
    // Get the audio URL
    range = [string rangeOfString:@"http"];
    string = [string substringFromIndex:range.location];
    string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    url = [NSURL URLWithString:string];
    NSLog(@"url:\n%@", url);
    
    // Get the Audio info
    request = [NSMutableURLRequest requestWithURL:url];
    data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"string:\n%@", string);
    
    // Get the first chunk URL
    range = [string rangeOfString:@"http"];
    string = [string substringFromIndex:range.location];
    range = [string rangeOfString:@"#"];
    string = [string substringToIndex:range.location];
    
    string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    url = [NSURL URLWithString:string];
    NSLog(@"url: %@", url);
    
    // Get the first audio chunk
    request = [NSMutableURLRequest requestWithURL:url];
    [NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                               if ( !error ) {
                                   NSLog(@"data: %@", [data subdataWithRange:NSMakeRange(0, 20)]);
                                   NSLog(@"data+296: %@", [data subdataWithRange:NSMakeRange(296, 20)]);
                                   //                                       [self audioFileReaderWithData:data andFileName:fileName];
    
                               }
                               else {
                                   NSLog(@"downloadDataWithUrl failed");
                               }
                           }];
    

    Output:

    SingleView[19993:1612455] url:
    http://playlists.ihrhls.com/c5/1469/playlist.m3u8?listeningSessionID=54868d904e0d78ec_5989234_FIJrewys_000000NAxC3&downloadSessionID=0
    
    string:
    #EXTM3U
    #EXT-X-ALLOW-CACHE:NO
    #EXT-X-TARGETDURATION:11
    #EXT-X-MEDIA-SEQUENCE:0
    #EXTINF:10,title="Z100",artist="NY's #1 Hit Music Station",url="song_spot=\"T\" MediaBaseId=\"0\" itunesTrackId=\"0\" amgTrackId=\"0\" amgArtistId=\"0\" TAID=\"0\" TPID=\"0\" cartcutId=\"0\" amgArtworkURL=\"\" length=\"00:00:00\" unsID=\"0\""
    http://chunks.ihrhls.com/1469/0GmnHSSGis2-245920-10031.aac
    #EXTINF:10,title="Z100",artist="NY's #1 Hit Music Station",url="song_spot=\"T\" MediaBaseId=\"0\" itunesTrackId=\"0\" amgTrackId=\"0\" amgArtistId=\"0\" TAID=\"0\" TPID=\"0\" cartcutId=\"0\" amgArtworkURL=\"\" length=\"00:00:00\" unsID=\"0\""
    http://chunks.ihrhls.com/1469/AA2skPqDDCc-245921-9984.aac
    #EXTINF:10,title="Z100",artist="NY's #1 Hit Music Station",url="song_spot=\"T\" MediaBaseId=\"0\" itunesTrackId=\"0\" amgTrackId=\"0\" amgArtistId=\"0\" TAID=\"0\" TPID=\"0\" cartcutId=\"0\" amgArtworkURL=\"\" length=\"00:00:00\" unsID=\"0\""
    http://chunks.ihrhls.com/1469/Dzt4rpXJBlg-245922-9984.aac
    
    url: http://chunks.ihrhls.com/1469/0GmnHSSGis2-245920-10031.aac
    
    data: 49443304 00000000 021e5449 54320000 00050000
    
    data+296: fff95c40 21c00001 4a36298c c4489589 0150b166
    

    That is the first 20 bytes of the aac data desired and 296 bytes in is the value "FFF9" you are looking for.

    Answer to initial question: What you have after converting the hex in the question is:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
        <head>
            <title>The page is not found</title>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <style type="text/css">
                /*<![CDATA[*/
                body {
                    background-color: #fff;
                    color: #000;
                    font-size: 0.9em;
                    font-family: sans-serif,helvetica;
                    margin: 0;
                    padding: 0;
                }
                :link {
                    color: #c00;
                }
                :visited {
                    color: #c00;
                }
                a:hover {
                    color: #f50;
                }
                h1 {
                    text-align: center;
                    margin: 0;
                    padding: 0.6em 2em 0.4em;
                    background-color: #294172;
    

    Note in particular the title: "The page is not found".

    The URL is probably incorrect.