我正在开发一个APP,供用户将视频上传到我们的FTP服务器
到目前为止,一切都已基本完成但我遇到一个问题是用户上传视频(.MOV)后,我无法打开并播放文件。
quicktime播放器返回的错误消息是“因电影的文件格式无法识别而无法打开”
在我的代码中,我让用户使用ALAssetsLibrady
选择视频然后将视频加载到ALAsset对象中,在开始上传之前,将视频从ALAsset加载到NSInputStream对象中,这是代码。
ALAssetRepresentation *rep = [currentAsset defaultRepresentation];
Byte *buffer = (Byte*)malloc(rep.size);
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
iStream = [NSInputStream inputStreamWithData:data];
[iStream open];
下一步是设置NSOutputStream并打开它,通过以下代码处理上传操作。
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
switch (eventCode) {
case NSStreamEventNone:
{
break;
}
case NSStreamEventOpenCompleted:
{
//opened connection
NSLog(@"opened connection");
break;
}
case NSStreamEventHasBytesAvailable:
{
// should never happen for the output stream
[self stopSendWithStatus:@"should never happen for the output stream"];
break;
}
case NSStreamEventHasSpaceAvailable:
{
// If we don't have any data buffered, go read the next chunk of data.
NSInteger bufferSize = 65535;
uint8_t *buffer = malloc(bufferSize);
if (bufferOffset == bufferLimit) {
NSInteger bytesRead = [iStream read:buffer maxLength:bufferSize];
if (bytesRead == -1) {
[self stopSendWithStatus:@"file read error"];
} else if (bytesRead == 0) {
[self stopSendWithStatus:nil];
} else {
bufferOffset = 0;
bufferLimit = bytesRead;
}
}
// If we're not out of data completely, send the next chunk.
if (bufferOffset != bufferLimit) {
NSInteger bytesWritten = [oStream write:&buffer[bufferOffset] maxLength:bufferLimit - bufferOffset];
if (bytesWritten == -1) {
[self stopSendWithStatus:@"file write error"];
} else {
bufferOffset += bytesWritten;
}
}
//NSLog(@"available");
break;
}
case NSStreamEventErrorOccurred:
{
//stream open error
[self stopSendWithStatus:[[aStream streamError] description]];
break;
}
case NSStreamEventEndEncountered: //ignore
NSLog(@"end");
break;
}
}
没有任何错误发生,视频文件确实上传到FTP文件大小和名称正确,但无法打开它。
有人知道任何线索吗?
答案 0 :(得分:1)
我为流式ALAsset对象制作了NSInputStream实现 - POSInputStreamLibrary。它不会将整个1GB视频作为您的解决方案读入内存,而是使用块来读取电影。当然,这不是POSBlobInputStream的唯一功能。更多关于我的GitHub存储库的信息。
答案 1 :(得分:0)
我知道这可能不是您正在寻找的答案,但您不应该通过FTP使用直接连接来允许用户将文件上传到您的网络服务器。与REST相比,这是不安全和缓慢的。
相反,为什么不写一点点的PHP来处理上传,并通过REST从应用程序发布文件?这里:
$uploaddir = 'uploads/';
$file = basename($_FILES['file']['name']);
$uploadfile = $uploaddir . $file;
我还建议使用AFNetworking来处理POST请求http://afnetworking.com/
答案 2 :(得分:0)
首先,我想您的意思是通过将ALAsset
转换为NSInputStream
而不是NSData
来减少内存容量。但是您先将其转换为NSData
然后转换为NSData
{1}}您必须NSInputStream
,它没有意义,并且不会因为NSData
已将视频放入内存而无法降低内存容量。
因此,如果您想通过Stream
传输视频以减少内存压力(或者您没有选择,因为您的视频最高可达2GB或更多),则应使用CFStreamCreateBoundPair
上传按块查看文件块,请参阅下面的Apple iOS Developer Library。
对于大块构造数据,调用CFStreamCreateBoundPair创建一对流,然后调用setHTTPBodyStream:方法告诉NSMutableURLRequest使用其中一个流作为其主体内容的源。通过写入另一个流,您可以一次发送一个数据。
我在github中通过ALAsset
快速转换NSInputStream
到CFStreamCreateBoundPair
。关键点就像撰写的文档一样。另一个参考是{{3 }}
希望它对你有所帮助。