通过流获取帧并在屏幕上显示
Posted
技术标签:
【中文标题】通过流获取帧并在屏幕上显示【英文标题】:Getting frames though a stream and display on screen 【发布时间】:2015-05-27 11:47:41 【问题描述】:我需要从服务器流式传输并在屏幕上显示流式传输的内容...使用 NSStream、NSInputStream 和 NSOutputStream 流式传输工作正常。如何在屏幕上显示它?
使用的流看起来像@"http://191.168.143.41:1212/;
if(stream == inputStream)
uint8_t buf[1024];
unsigned int len = 0;
len = [inputStream read:buf maxLength:1024];
if(len > 0)
NSMutableData* datas=[[NSMutableData alloc] initWithLength:0];
[datas appendBytes: (const void *)buf length:len];
NSString *s = [[NSString alloc] initWithData:datas encoding:NSASCIIStringEncoding];
[self readIn:s];
NSLog(@"ss%@",s);
[self loadMovie:s]; //method for movie player
我试图在下面的电影播放器中显示它..
-(void_loadMovie:(NSString*)moviePrefix
NSString *path = [NSString stringWithFormat:@"%@.mjpg", moviePrefix];
NSURL *url = [NSURL fileURLWithPath:path];
if (url)
_moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
_moviePlayer.view.frame = CGRectMake(0, 70, 600, 450);
_moviePlayer.controlStyle = MPMovieControlStyleNone;
_moviePlayer.scalingMode = MPMovieScalingModeNone;
[dic setObject:__moviePlayer forKey:path];
[_moviePlayer prepareToPlay];
[self.view addSubview: _moviePlayer.view];
[self.view bringSubviewToFront:_moviePlayer.view];
[self.view addSubview: _moviePlayer.view];
[_moviePlayer play];
是 NSString *path = [NSString stringWithFormat:@"%@.mjpg", moviePrefix];正确的方法??
这显示黑屏。什么问题? 如果这种方式不正确,还有其他方法可以显示这些帧吗? 谁能帮我解决这个问题...
【问题讨论】:
NSString *path = [NSString stringWithFormat:stringWithFormat:@".mjpeg", moviePrefix, @"movie"];
你为什么要使用stringWithFormat:
两次
@OmerWaqasKhan 抱歉,这是一个拼写错误。
【参考方案1】:
MJPEG 只是一个接一个地发送的 JPEG。
几年前我在这方面工作。
在 ios 版本(iOS5?)上,使用UIWebView
很容易阅读,但 iOS 的更新打破了这一切。这打破了我目前的所有工作。
也许UIWebView
今天可以再次成功(修复)。
无论如何,由于它只是一堆 JPEG,您可以只读取 JPG(检测 JPG 文件的开始/结束),创建 JPG 图像并将其显示在 UIImageView
中。
一种解决方法(未经测试),但您应该了解整个想法:
//属性
@property (nonatomic, strong) NSMutableData *data;
@property (nonatomic, weak) IBOutlet UIImageView *streamImageView;
//在某处初始化
_data = [[NSMutableData alloc] init];
//在流委托方法中:
//Start JPG: FFD8 — End JPG: FFD9
UInt8 startJPEGBytes[2];
startJPEGBytes[0] = 0xFF;
startJPEGBytes[1] = 0xD8;
NSData *startData = [NSData dataWithBytes:&startJPEGBytes length:2];
UInt8 endJPEGBytes[2];
endJPEGBytes[0] = 0xFF;
endJPEGBytes[0] = 0xD9;
NSData *endData = [NSData dataWithBytes:&endJPEGBytes length:2];
[_data appendBytes: (const void *)buf length:len];
NSRange startRange = [_data rangeOfData:startData options:0 range:NSMakeRange(0, [_data length])];
if (startRange.location != NSNotFound) //We found the start of a JPEG
NSRange endRange = [_data rangeOfData:endData options:0 range:NSMakeRange(startRange.location, [_data length]-startRange.location)];
if (endRange.location != NSNotFound) //We found the end of a JPEG
NSRange imageRange = NSMakeRange(startRange.location, endRange.location+endRange.length-startRange.location);
NSData *imageData = [_data subDataWithRange: imageRange];
streamImage = [UIImage imageWithData:imageData];
[_streamImageView setImage:streamImage];
[_data replaceBytesInRange:NSMakeRange(0, imageRange.location+imageRange.length withBytes:NULL length:0]; //We remove the start till the end of JPEG frame. Start at 0, since there could be garbage at the start.
【讨论】:
【参考方案2】:您没有在字符串中添加moviePrefix
NSString *path = [NSString stringWithFormat:@".mjpg", moviePrefix, @"movie"];
改成
NSString *path = [NSString stringWithFormat:@"%@.mjpg", moviePrefix, @"movie"];
【讨论】:
您没有收到任何与此相关的警告吗? 最后的@"movie"
仍然没有被使用。也许@"%@%@.mjpg"
?
这个@"movie"
是什么?它来这里的目的是什么?对不起,我无法理解。
@OmerWaqasKhan 纠正错误,@"movie" 不需要,我在一个例子中看到过。但是播放器仍然显示黑屏
您尝试过在任何浏览器上流式传输 URL 吗?【参考方案3】:
https://github.com/horsson/mjpeg-iphone/tree/55251a85e2c2489014036ddf5a491783f9b1962d
用它来获取流和显示。它的工作原理
【讨论】:
以上是关于通过流获取帧并在屏幕上显示的主要内容,如果未能解决你的问题,请参考以下文章
如何通过鼠标移动事件获取相机位置并在three.js中转换为屏幕坐标? [关闭]
通过 SurfaceTexture 在 GLSurfaceView 上显示相机流
如何在 Swift iOS 中仅在最后一个屏幕上获取导航栏?