`
xujinquan19
  • 浏览: 150548 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

iOS音视频封装与传输demo

 
阅读更多
ios没有直接得api用来封装传输rtp,但是经常有用到得接收过来得音视频数据,经过X264处理转换便可以封装为Rtp包进行直接发送。大家可以看代码:
  1. #include "rtpsession.h"
  2. #include "rtppacket.h"
  3. #include "rtpudpv4transmitter.h"
  4. #include "rtpipv4address.h"
  5. #include "rtpsessionparams.h"
  6. #include "rtperrors.h"

  7. @interface VideoRTPPack : NSObject<SocketHandlerDelegate>
  8. {
  9.         RTPSession          m_RTPSession;
  10.        
  11.         NSMutableDictionary *dicDataBuffer;
  12. }

  13. @property(nonatomic, retain) NSMutableDictionary *dicDataBuffer;

  14. - (id)initWithVideoRTP:(NSString *)hostIP onPort:(unsigned short)port;

  15. - (void)createVideoRTP:(NSString *)host onPort:(unsigned short)port;

  16. - (void)SendVideoPacket:(unsigned char*)videoData
  17.                                         Nal:(int)_nal
  18.                                    Size:(size_t)videoDataSize
  19.                                    User:(unsigned long)user_id
  20.                                 FrameID:(int)video_frame_id;

  21. - (void)resendSubPacketData:(int)frameID withSubPack:(int)packID;

  22. - (void)closeVideoRTP;

  23. @end
复制代码
  1. #import "VideoRTPPack.h"

  2. @implementation VideoRTPPack

  3. @synthesize dicDataBuffer;

  4. - (id)initWithVideoRTP:(NSString *)hostIP onPort:(unsigned short)port
  5. {
  6.         if (self = [super init])
  7.         {
  8.                 [self createVideoRTP:hostIP onPort:port];
  9.                
  10.                 dicDataBuffer = [[NSMutableDictionary alloc] init];
  11.         }
  12.        
  13.         return self;
  14. }

  15. - (void)dealloc
  16. {
  17.         KLC_RELEASE_SAFELY(self.dicDataBuffer)
  18.        
  19.         [super dealloc];
  20. }

  21. - (void)createVideoRTP:(NSString *)host onPort:(unsigned short)port
  22. {
  23.         RTPUDPv4TransmissionParams m_VideoTransparams;
  24.         RTPSessionParams m_VideoSessionparams;
  25.        
  26.         m_VideoSessionparams.SetOwnTimestampUnit(1.0/10.0);
  27.         m_VideoSessionparams.SetAcceptOwnPackets(TRUE);
  28.         m_VideoSessionparams.SetUsePollThread(0);
  29.         m_VideoTransparams.SetPortbase(port);
  30.        
  31.         int nStatus = m_RTPSession.Create(m_VideoSessionparams, &m_VideoTransparams);
  32.         if(nStatus < 0)
  33.         {
  34.                 NSLog(@"create rtp faild!");
  35.                 return;
  36.         }
  37.        
  38.         unsigned long ipAddress = ntohl(inet_addr([host UTF8String]));
  39.        
  40.         RTPIPv4Address JRTPVideoAddr(ipAddress, port);
  41.         nStatus = m_RTPSession.AddDestination(JRTPVideoAddr);
  42.         if(nStatus < 0)
  43.         {
  44.                 NSLog(@"add destination faild!");
  45.                 return;
  46.         }
  47.        
  48.         m_RTPSession.SetDefaultPayloadType(96);
  49.         m_RTPSession.SetDefaultMark(FALSE);
  50.         m_RTPSession.SetDefaultTimestampIncrement(160);
  51. }

  52. - (void)SendVideoPacket:(unsigned char*)videoData
  53.                                         Nal:(int)_nal
  54.                                    Size:(size_t)videoDataSize
  55.                                    User:(unsigned long)user_id
  56.                                 FrameID:(int)video_frame_id
  57. {
  58.         NSLog(@"video_frame_id = %d", video_frame_id);
  59.        
  60.         unsigned short length = 0;
  61.         int subPackIndex = 1;
  62.         int i_video_loop = 0, offset = 0, video_pack_len = 0;
  63.         NSMutableArray *subPackArray = [[NSMutableArray alloc] init];
  64.        
  65.         MSQ_PACK_MID msq_pack_mid;
  66.         strcpy(msq_pack_mid.msq_head.AppName, GAppName);
  67.         msq_pack_mid.msq_head.sTransType  = htons(TRANSTYPE_CLIENTTOSERVER);
  68.         msq_pack_mid.msq_head.sDataType   = htons(SENDSTREAM_VIDEO_DATATYPE);
  69.         msq_pack_mid.msq_head.lSendID     = htonl(user_id);
  70.        
  71.         i_video_loop = videoDataSize / VIDEO_PACKET_SIZE;
  72.         if ((videoDataSize % VIDEO_PACKET_SIZE) > 0) i_video_loop ++;
  73.        
  74.         while (videoDataSize)
  75.         {
  76.                 VideoPacket *pVideoPacket = (VideoPacket*)msq_pack_mid.msq_data;
  77.                
  78.                 pVideoPacket->PacketHead.TotalPackets   = i_video_loop;
  79.                 pVideoPacket->PacketHead.subpacketindex = subPackIndex;
  80.                 pVideoPacket->PacketHead.sOffset        = htons(offset);
  81.                
  82.                 video_pack_len = (videoDataSize < VIDEO_PACKET_SIZE) ? videoDataSize:VIDEO_PACKET_SIZE;
  83.                 pVideoPacket->PacketHead.sDataLength    = htons(video_pack_len);
  84.                 videoDataSize = videoDataSize - video_pack_len;
  85.                
  86.                 pVideoPacket->PacketHead.lFrameID       = htonl(video_frame_id);
  87.                 pVideoPacket->PacketHead.timeStart      = 0;
  88.                 pVideoPacket->PacketHead.timeEnd        = 0;
  89.                 pVideoPacket->PacketHead.s_nal          = _nal;
  90.                
  91.                 memcpy(pVideoPacket->rawData, videoData+offset, video_pack_len);
  92.                 offset = offset + video_pack_len;
  93.                
  94.                 length = sizeof(VideoPacketHead) + video_pack_len;
  95.                
  96.                 msq_pack_mid.msq_head.sTCPLength = htons(length);
  97.                 msq_pack_mid.msq_head.sDataLength = msq_pack_mid.msq_head.sTCPLength;
  98.                
  99.                 NSData *subData = [NSData dataWithBytes:(void *)&msq_pack_mid length:sizeof(MSQ_HEAD)+length];
  100.                 [subPackArray addObject:subData];
  101.                
  102.                 m_RTPSession.SendPacket(&msq_pack_mid, sizeof(MSQ_HEAD)+length);
  103.                
  104.                 subPackIndex ++;
  105.         }
  106.        
  107.         // 把视频数据存入缓冲区
  108.         if ([[self.dicDataBuffer allKeys] count] < 50)
  109.         {
  110.                 [self.dicDataBuffer setObject:subPackArray
  111.                                                            forKey:[NSNumber numberWithInt:video_frame_id]];
  112.         }
  113.         else
  114.         {
  115.                 [self.dicDataBuffer removeObjectForKey:[NSNumber numberWithInt:video_frame_id-51]];
  116.                 [self.dicDataBuffer setObject:subPackArray
  117.                                                            forKey:[NSNumber numberWithInt:video_frame_id]];
  118.         }
  119.        
  120.         KLC_RELEASE_SAFELY(subPackArray)
  121. }

  122. - (void)resendSubPacketData:(int)frameID withSubPack:(int)packID
  123. {
  124.         NSArray *lostArray = (NSArray *)[self.dicDataBuffer objectForKey:[NSNumber numberWithInt:frameID]];
  125.         NSData *lostData = [lostArray objectAtIndex:packID-1];
  126.        
  127.         int nStatus = m_RTPSession.SendPacket([lostData bytes], [lostData length]);
  128.         if (nStatus == 0) NSLog(@"ReSend Packet Data Succeed!");
  129. }

  130. - (void)closeVideoRTP
  131. {
  132.         if (m_RTPSession.IsActive())
  133.         {
  134.                 m_RTPSession.Destroy();
  135.         }
  136. }


  137. @end
demo程序如附件中

 

分享到:
评论

相关推荐

    iOS音视频硬件编码源码,iOS原生不包含任何三方库音视频编码源码demo

    这个压缩包文件提供的"iOS音视频硬件编码源码"是一个不依赖任何第三方库的原生实现,利用了Apple提供的两个核心框架:AudioToolbox和VideoToolbox。这两个框架是iOS系统内建的,专为音频和视频处理设计,提供了高效...

    ios视频通话demo

    在iOS平台上实现视频通话功能,通常涉及到多个技术层面,包括音视频采集、编码、传输以及解码和渲染等。以下是对这些关键知识点的详细说明: 1. **音视频采集**: - **音频采集**:iOS设备上的音频采集通常通过...

    iOS fFmpeg软解码demo

    在这个"iOS ffmpeg软解码demo"中,我们将深入探讨如何在iOS应用中使用`ffmpeg`进行软解码,以实现对音视频数据的高效处理。 软解码是指通过CPU来执行的解码过程,与硬件解码(使用GPU或专用硬件)相比,可能会消耗...

    OS视频通话/直播demo

    在iOS平台上实现视频通话和直播功能,涉及到一系列的技术和组件,包括音视频采集、编码、传输、解码和渲染等步骤。以下是对这些关键知识点的详细讲解: 1. **音视频采集**:在iOS设备上,我们可以使用AVFoundation...

    iOS FFmpeg软编码demo

    在iOS平台上,FFmpeg被用于音视频的编码、解码、转码、播放等多个场景。本文将详细探讨iOS上使用FFmpeg进行软编码的原理和实践。 首先,软编码是指通过CPU执行的编码过程,而不是依赖硬件加速。在iOS上,由于设备...

    iOS开发中一些实用的Demo.zip

    开发者可以学习如何裁剪图片、滤镜处理,以及如何播放和录制音视频。 8. 地图与定位服务: 如果涉及到地图应用,Demo可能包含了使用Apple MapKit或第三方库如Google Maps SDK,学习如何显示地图、添加标注、获取...

    ios-基于AVPlayer封装的简单播放器view.zip

    总的来说,这个项目提供了一个使用AVPlayer封装的基础播放器,对于iOS开发者来说,通过研究这个项目,不仅可以了解AVPlayer的基本用法,还能学习到如何进行组件封装,以及如何与其他系统服务(如音视频资源加载、...

    starrtc-ios-demo

    6. **多路复用与传输控制**:RTC应用需要处理多个音视频流的同时传输,这涉及到多路复用(multiplexing)技术,如RTP/RTCP协议。同时,为了保证流畅性,还需要有适当的带宽控制策略。 7. **用户界面设计**:演示...

    ios-基于ijkplayer framework做的视频播放demo

    ijkplayer源于FFmpeg项目,FFmpeg是一个著名的音视频处理开源库。ijkplayer将FFmpeg进行了封装,使其更易于在移动平台上使用,同时提供了更友好的API接口和更好的性能优化。它的主要优势在于对多种视频格式的支持...

    mac QuickTime hevc h265 mp4 demo iOS 视频示例

    这个“mac QuickTime hevc h265 mp4 demo iOS 视频示例”是一个特别针对iOS设备和macOS系统演示如何使用QuickTime Player播放HEVC(High Efficiency Video Coding)和H.265编码的MP4视频的实例。 HEVC/H.265是一种...

    ios-简易的音视屏播放框架XYQPlayer.zip

    一直都想好好学学音视频这方面的知识,抽了几个周末参考一些资料,尝试着写了一个简易的音视频播放框架,支持音视频播放、音乐缓存,其实吧,也就是尽可能的封装罢了,方便以后自己使用。目前只是开始,可能有些不足...

    ios-通讯软件中的语音录制与播放.zip

    `ios-通讯软件中的语音录制与播放.zip`这个压缩包提供了一个Demo,它封装了两个关键控件:一个是用于语音录制,另一个是用于语音播放。这样的设计便于开发者快速集成到自己的应用中。 首先,我们要理解语音录制的...

    unity视频对话插件Demo.zip_DEMO_unity_unity视频对话插件Demo_聊天室视频_视频聊天室

    2. **视频编码与解码**:在视频对话中,视频数据需要经过编码才能在网络上传输,然后在接收端解码。常见的视频编解码器有H.264、VP8和VP9等。插件可能已经封装了这些编解码过程,以便开发者可以简单地调用接口。 3....

    腾讯im对接简易封装腾讯im对接简易封装

    腾讯IM提供了包括单聊、群聊、音视频通话、文件传输等多种功能。为了在自己的应用中集成这些功能,开发者需要注册并创建应用,获取到必要的AppID和AppKey,这是与腾讯IM服务器交互的身份凭证。 接下来,我们进入...

    vue集成环信demo(包括视频通话)

    - 音频/视频通话:集成环信的音视频通话接口,创建相应的UI组件,并处理通话的发起、接受、挂断等操作。 5. **Demo详解**: - `Vue-demo-master`压缩包中包含了完整的Vue项目结构,你可以在本地通过Vue CLI或...

    android 视频通讯demo

    这里我们主要探讨的是一个基础的视频通讯Demo,它专注于视频通话功能,仅支持视频流的捕获和传输。 1. **视频采集**: - **Camera API**:Android提供了Camera API用于访问和控制设备的摄像头。在Demo中,开发者...

    IOS IJKMdia 直播库

    它的核心是基于 FFmpeg,一个知名的跨平台多媒体处理库,为开发者提供了灵活且高效的音视频解码和播放能力。在 iOS 开发中,IJKPlayer 是 IJKMedia 在这个平台上的实现,它不仅支持 iOS 设备,还兼容了 Android 平台...

    xmpp ios demo

    本“xmpp iOS demo”是一个示例项目,旨在帮助开发者了解如何在iOS应用中集成并使用XMPP框架进行即时通讯功能的开发。 首先,我们需要了解XMPP的基本概念。XMPP的核心是Jabber协议,它构建在TCP/IP之上,通过XML...

    swift-网易云信官网的demo功能太复杂.将IM.音视频.功能抽离出来

    6. **性能优化**:针对不同的应用场景,对代码进行优化,例如消息推送的延迟优化,音视频通话的带宽控制等。 7. **兼容性测试**:确保抽离出来的组件在不同的设备和操作系统版本上都能正常工作。 8. **单元测试**...

Global site tag (gtag.js) - Google Analytics