http://blog.csdn.net/u013028303/article/details/41308519
写作前面:继能够播放本地的.h264文件后,就只剩最后一个功能——播放网络视频了。这个工程用的时socket接受数据的方式。
主要的思路是:主要有三个线程,主线程负责显示图片,线程二负责解码,线程三负责接收网络数据。当用户点击播放开始建立socket连接,然后启动解码线程,并循环从线程三取数据来解码。
一、准备工作
1.点击下载AsyncSocket库文件,并将AsyncSocket.h、AsyncSocket.m添加到工程中。
2.添加CFNetwork.framework。
二、建立连接
- AsyncSocket *asyncSocket;
- <span style="font-size:18px;"> NSError *err = nil;
- NSString *serveIP = @"10.0.0.29";
- const UInt16 port = 8000;
- asyncSocket = [[AsyncSocket alloc] initWithDelegate:self];
- NSLog(@"serveIP is %@",serveIP);
- if (![asyncSocket connectToHost:serveIP onPort:port error:&err]) {
- NSLog(@"Error: %@",err);
- }
- [asyncSocket readDataWithTimeout:-1 tag:0];//开始接受数据
- </span>
在这里我直接写了固定的IP地址以及端口,当然也可以一个textField来填写IP。
- -(void)textFieldDidBeginEditing:(UITextField *)textField{
- [textField becomeFirstResponder];
- }
- -(BOOL)textFieldShouldReturn:(UITextField *)textField{
- [textField resignFirstResponder];
- serveIP = textField.text;
- [ipField removeFromSuperview];
- return YES;
- }
当点击textfield时响应并弹出键盘,完成输入时将输入的值赋给serveIP然后销毁textfield。
三、接受数据
- NSMutableData *dataAll = [[NSMutableData alloc] init];//用来累积每次收到的数据
- <pre name="code" class="objc"><span style="font-family: Arial, Helvetica, sans-serif;">-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{</span><span style="font-family: Arial, Helvetica, sans-serif;"> </span>
[dataAll appendData:data];}
这个函数是AsyncSocket判断收到数据时自动执行的函数,在这里我用一个MutableData来累积每次data的数据。
四、内存拷贝的函数
- NSMutableData *dataTem = [[NSMutableArray alloc] init];
- -(BOOL)memoryCopy{
- dataTem = [dataAll copy];
- NSLog(@"拷贝完成!");
- [dataAll init];
- isReceive = NO;
- return YES;
- }
当解码开始或者完成时调用该函数,把dataAll也就是累积下来的数据传送到dataTem也就是解码数据Buff中。
五、修改解码函数
- while (!playButton.enabled) {
- [self memoryCopy];
- readBuf = [dataTem bytes];
- if(readFileLen <= 0){
- }else{
- int handleLen = 0;
- int handleFileLen = [dataTem length];
- while(handleFileLen >0){
- int nLength = av_parser_parse2(avParserContext,codec_, &parseBuf, &parseBufLen, readBuf + handleLen, handleFileLen, 0, 0, 0);//查找264帧头
- handleFileLen -= nLength;
- handleLen += nLength;
- if(parseBufLen <= 0){
- continue;
- }else{
- }
- packetBuf.size = parseBufLen;
- packetBuf.data = parseBuf;
- while (packetBuf.size > 0) {
- int decodeLen = avcodec_decode_video2(codec_, pFrame_, &frameFinished, &packetBuf);
- if(decodeLen <= 0){
- break;
- }
- packetBuf.size -= decodeLen;
- packetBuf.data += decodeLen;
- if (frameFinished >0) {
- avpicture_get_size(PIX_FMT_RGB24, codec_->width, codec_->height);
- [self performSelectorOnMainThread:@selector(displayPhoto) withObject:nil waitUntilDone:YES];
- [NSThread sleepForTimeInterval:0.02];
- }
- }
- }
- }
- }
将上一篇播放本地h264文件的解码函数替换成这个,当按键按下时
- [playButton setEnabled:NO];
这样就完成了网络视频流的播放。
浙公网安备 33010602011771号