我正在尝试从iOS发布到我的PHP服务器,并让PHP服务器使用base64_encode将二进制文件返回到我的iOS应用。
该文件下载到我的iOS设备,但是AVAsset告诉我该文件不可播放,我无法弄清楚我的错误在哪里。我还确保每个标题在服务器上都是有效的.wav和.mp3文件。
相关的PHP文件部分:
$song_to_download = $_POST['title'];
...(check if file exists, open 'rb', etc)
while (!feof($fp))
{
$block = fread($fp, 57 * 143); // based on php.net base64_encode examples
$base64 = base64_encode($block);
print $base64;
}
相关的iOS代码:
- (NSUInteger) getFileSizeLocal:(NSString *)path
{
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error;
NSDictionary *dict = [fm attributesOfItemAtPath:path error:&error];
if (dict == nil)
{
NSLog(@"getFileSize - ERROR reading file attributes <%@>", error.localizedDescription);
return 0;
}
return [dict[NSFileSize] unsignedIntegerValue];
}
-(void)URLSession:(NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(nonnull NSURL *)location
{
// decode the base64 'location' file and write it to the final file
NSString *path = location.absoluteString;
if (path.length < 8) {
NSLog(@"ERROR - <%@> length is less than 8", path);
return;
}
NSInteger fileStrLen = 7; // 'file://' length - we keep the first / so its a complete hard path in the filesystem
NSString *filepath = [path substringWithRange:NSMakeRange(fileStrLen, path.length - fileStrLen)]; // strip off 'file://' portion first
if ([[NSFileManager defaultManager] fileExistsAtPath:filepath] == NO)
{
NSLog(@"ERROR - file does NOT exists at path <%@>", filepath);
return;
}
NSFileHandle *fpi = [NSFileHandle fileHandleForReadingAtPath:filepath];
NSUInteger len = [self getFileSizeLocal:filepath];
if (len == 0) {
NSLog(@"ERROR - filesize is zero");
return;
}
NSFileHandle *fpo = [NSFileHandle fileHandleForWritingAtPath:_largePathAndFileToWrite];
if (fpo == nil)
{
[[NSFileManager defaultManager] createFileAtPath:_largePathAndFileToWrite contents:nil attributes:nil];
fpo = [NSFileHandle fileHandleForWritingAtPath:_largePathAndFileToWrite];
}
// Read tmp input file (filepath), WRITE to final filename (_largePathAndFileToWrite)
NSData *data = nil;
NSData *decoded64Data = nil;
NSString *base64String = nil;
NSUInteger step_size = 10868; // based on php.net base64_encode examples
@autoreleasepool
{
for (NSUInteger x = 0; x < len; x += step_size)
{
data = [fpi readDataOfLength:step_size];
base64String = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
decoded64Data = [base64String dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
if (decoded64Data == nil)
{
NSLog(@"ERROR - failed to decode data from tmp input file at idx <%ld>", (long)x);
break;
}
[fpo seekToEndOfFile];
[fpo writeData:decoded64Data];
}
}
[fpo closeFile];
[fpi closeFile];
NSURL *fileURL = [NSURL fileURLWithPath:_largePathAndFileToWrite];
AVAsset *asset = [AVURLAsset URLAssetWithURL:fileURL options:nil];
if (asset.isPlayable) {
NSLog(@"GOOD");
}
if (asset.isReadable) {
NSLog(@"READABLE");
}
else {
NSLog(@"Asset is BAD %@", _largePathAndFileToWrite);
}
}
我的输出始终显示“资产不佳”
我正在尝试的文件大小小于50M字节,并且 服务器的大小与iOS设备上最终文件的大小相同 下载。
当我尝试用AVAudioPlayer播放它时,它总是失败:
The operation couldn't be completed.
感谢您的帮助。我花了几个小时试图找出答案。
谢谢!
[已解决]
我正在努力做到这一点。原来我可以转让 作为没有base64编码的二进制文件。这是最终的解决方案 任何也需要它的人:
PHP方面:(适用于.mp3 .wav .m4a,其他未尝试使用的
<?php
$filepath = "./slist/mysong.mp3";
if (file_exists($filepath)) {
header('Content-Type: application/octect-stream');
header('Content-Description: File Transfer');
header('Content-Length: ' . filesize($filepath));
ob_clean();
flush();
readfile($filepath);
}
?>
ios代码:
-(void)URLSession:(NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(nonnull NSURL *)location
{
NSLog(@"downloadTask - didFinishDownloadingToURL <%@>", location.absoluteString);
// decode the base64 'location' file and write it to the final file
NSString *path = location.absoluteString;
if (path.length < 8) {
NSLog(@"ERROR - <%@> length is less than 8", path);
return;
}
NSInteger fileStrLen = 7; // 'file://' length - we keep the first / so its a complete hard path in the filesystem
NSString *filepath = [path substringWithRange:NSMakeRange(fileStrLen, path.length - fileStrLen)]; // strip off 'file://' portion first
if ([[NSFileManager defaultManager] fileExistsAtPath:filepath] == NO)
{
NSLog(@"ERROR - file does NOT exists at path <%@>", filepath);
return;
}
// Just Move it into place
NSError *error;
if ([[NSFileManager defaultManager] moveItemAtPath:filepath toPath:_largePathAndFileToWrite error:&error] == NO)
{
NSLog(@"ERROR - failed to move file - <%@>", error.localizedDescription);
return;
}
}