免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 10098 | 回复: 7
打印 上一主题 下一主题

linux下面如何用ffmpeg将h264帧数据村存为FLV文件!! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-10-19 10:08 |只看该作者 |倒序浏览
最近一段时间一直在研究怎么将接收到的H264帧数据,存为一个FLV文件,初步的想法是用ffmpeg提供的开源库来实现,但因为之前一直没接触过这个,具体怎么做还是一筹莫展,各位前辈有没有之前做过这个

的,提供一些经验呗!!!

或者不用ffmpeg,有别的方案也行,但在转换效率以及稳定性上要求很高,因为这是服务器上要做的功能,而且数据量会特别庞大。。。。。

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
2 [报告]
发表于 2011-10-19 10:18 |只看该作者
靠, 这个我作过, FLV 的文件格式非常简单, 直接找 adobe 的说明, 照着写就行了

论坛徽章:
0
3 [报告]
发表于 2011-10-19 10:52 |只看该作者
是不是直接就拿H264的帧往flv的tag里面放,然后那些header自己根据帧的信息去构造啊!!照这么说,ffmpeg岂不根本用不到了啊!!!

论坛徽章:
0
4 [报告]
发表于 2011-10-19 10:52 |只看该作者

论坛徽章:
0
5 [报告]
发表于 2011-10-19 10:56 |只看该作者
一个是压缩算法,一个是存储格式。你要是只保持成文件,按格式存就是了。
不解码的话,应该不涉及ffmpeg。

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
6 [报告]
发表于 2011-10-19 11:07 |只看该作者
本帖最后由 zylthinking 于 2011-10-19 11:08 编辑

那我也不卖渔了, 摘些代码

  1. static char* g_lastKeyFrame = NULL;
  2. static int g_keyfrm_buf = 0;
  3. static int g_keyfrm_len = 0;

  4. int FlvSaveKeyFrame(void* data, int len){
  5.     if(len > g_keyfrm_buf){
  6.         free(g_lastKeyFrame);
  7.         g_lastKeyFrame = (char *) malloc(len);
  8.         if(g_lastKeyFrame == NULL){
  9.             g_keyfrm_len = 0;
  10.             return -1;
  11.         }
  12.         g_keyfrm_buf = len;
  13.     }

  14.     g_keyfrm_len = len;
  15.     if(len > 0){
  16.         memcpy(g_lastKeyFrame, data, g_keyfrm_len);
  17.     }
  18.     return 0;
  19. }

  20. int FlvGetLastKeyFrame(char*& buf){
  21.     buf = g_lastKeyFrame;
  22.     return g_keyfrm_len;
  23. }

  24. static char* g_sps_buf = NULL;
  25. static int g_sps_buf_len = 0;
  26. static int g_sps_len = 0;

  27. int FlvSaveSpsFrame(void* data, int len){
  28.     if(len > g_sps_buf_len){
  29.         free(g_sps_buf);
  30.         g_sps_buf = (char *) malloc(len);
  31.         if(g_sps_buf == NULL){
  32.             g_sps_buf_len = 0;
  33.             return -1;
  34.         }
  35.         g_sps_buf_len = len;
  36.     }

  37.     g_sps_len = len;
  38.     if(len > 0){
  39.         memcpy(g_sps_buf, data, g_sps_len);
  40.     }
  41.     return 0;
  42. }

  43. int FlvGetSpsFrame(char*& buf){
  44.     buf = g_sps_buf;
  45.     return g_sps_len;
  46. }

  47. static char* g_aac_buf = NULL;
  48. static int g_aac_buf_len = 0;
  49. static int g_aac_len = 0;

  50. int FlvSaveAacFrame(void* data, int len){
  51.     if(len > g_aac_buf_len){
  52.         free(g_aac_buf);
  53.         g_aac_buf = (char *) malloc(len);
  54.         if(g_aac_buf == NULL){
  55.             g_aac_buf_len = 0;
  56.             return -1;
  57.         }
  58.         g_aac_buf_len = len;
  59.     }

  60.     g_aac_len = len;
  61.     if(len > 0){
  62.         memcpy(g_aac_buf, data, g_aac_len);
  63.     }
  64.     return 0;
  65. }

  66. int FlvGetAacFrame(char*& buf){
  67.     buf = g_aac_buf;
  68.     return g_aac_len;
  69. }

  70. typedef int (*type_parser)(const char* flv_buffer, media_info& info);
  71. struct flv_media_parser{
  72.     DWORD fourcc;
  73.     type_parser parser;
  74. };

  75. //=========================================================

  76. // stupid compiler
  77. static void my_free(void* addr){
  78.     free(addr);
  79. }

  80. static int h264_parser(const char* flv_buffer, media_info& info){
  81.     info.bit_count = 0;
  82.     info.extra = 1;

  83.     int byte1 = ((int) flv_buffer[1]) & 0xff;
  84.     int byte2 = ((int) flv_buffer[2]) & 0xff;
  85.     int byte3 = ((int) flv_buffer[3]) & 0xff;
  86.     DWORD len = (byte1 << 16) | (byte2 << 8) | byte3;

  87.     int byte4 = ((int) flv_buffer[4]) & 0xff;
  88.     int byte5 = ((int) flv_buffer[5]) & 0xff;
  89.     int byte6 = ((int) flv_buffer[6]) & 0xff;
  90.     int byte7 = ((int) flv_buffer[7]) & 0xff;
  91.     int byte13 =  ((int) flv_buffer[13]) & 0xff;
  92.     int byte14 =  ((int) flv_buffer[14]) & 0xff;
  93.     int byte15 =  ((int) flv_buffer[15]) & 0xff;

  94.     info.dts = (byte7 << 24) | (byte4 << 16) | (byte5 << 8) | byte6;
  95.     int offset = (byte13 << 16) | (byte14 << 8) | byte15;
  96.     info.pts = info.dts + offset;

  97.     int byte12 = ((int) flv_buffer[12]) & 0xff;
  98.     if(byte12 == 0){
  99.         int sps_len = 0;
  100.         int pps_len = 0;
  101.         const char* sps = NULL;
  102.         const char* pps = NULL;

  103.         int nr_sps = ((int) flv_buffer[21]) & 0x1f;
  104.         if(nr_sps == 1){
  105.             int byte22 = ((int) flv_buffer[22]) & 0xff;
  106.             int byte23 = ((int) flv_buffer[23]) & 0xff;
  107.             sps_len = (byte22 << 8) | byte23;
  108.             sps = &flv_buffer[24];
  109.             pps = sps + sps_len;
  110.             sps_len += 4;
  111.         }else{
  112.             // no more than 1 sps currently
  113.             assert(nr_sps == 0);
  114.         }

  115.         int nr_pps = pps[0] & 0xff;
  116.         if(nr_pps == 1){
  117.             int byte1 = ((int) pps[1]) & 0xff;
  118.             int byte2 = ((int) pps[2]) & 0xff;
  119.             pps_len = ((byte1 << 8) | byte2) + 4;
  120.             pps = &pps[3];
  121.         }else{
  122.             pps = NULL;
  123.             // no more than 1 pps currently
  124.             assert(nr_pps == 0);
  125.         }

  126.         int header_len = sps_len + pps_len;
  127.         assert(header_len > 0);
  128.         unsigned char* buffer = (unsigned char *) malloc(header_len);
  129.         if(buffer == NULL){
  130.             return -1;
  131.         }

  132.         info.free = my_free;
  133.         info.length = header_len;
  134.         info.buffer = (char *) buffer;

  135.         if(sps_len > 0){
  136.             sps_len -= 4;

  137.             buffer[0] = sps_len >> 24;
  138.             buffer[1] = sps_len >> 16;
  139.             buffer[2] = sps_len >> 8;
  140.             buffer[3] = sps_len;
  141.             buffer += 4;
  142.             memcpy(buffer, sps, sps_len);
  143.             buffer += sps_len;
  144.         }

  145.         if(pps_len > 0){
  146.             pps_len -= 4;

  147.             buffer[0] = pps_len >> 24;
  148.             buffer[1] = pps_len >> 16;
  149.             buffer[2] = pps_len >> 8;
  150.             buffer[3] = pps_len;
  151.             buffer += 4;
  152.             memcpy(buffer, pps, pps_len);
  153.             buffer += pps_len;
  154.         }

  155.         return len + 11 + 4;
  156.     }else if(byte12 == 1){
  157.         info.length = len - 5;
  158.         info.buffer = (char *) &flv_buffer[16];
  159.         return len + 11 + 4;
  160.     }
  161.     return -1;
  162. }

  163. static flv_media_parser flv_h264_parser = {
  164.     make_fourcc('H', '2', '6', '4'),
  165.     h264_parser
  166. };

  167. static flv_media_parser* video_parser_of(char codec_id){
  168.     if(codec_id == (char) 0x07){
  169.         return &flv_h264_parser;
  170.     }
  171.     return NULL;
  172. }

  173. static int flv_video_unpack(const char* flv_buffer, media_info& info){
  174.     char byte11 = flv_buffer[11] & 0xff;
  175.     BOOL key_frame = (0x10 == (byte11 & 0xf0));
  176.     int codec_id = (byte11 & 0x0f);

  177.     flv_media_parser* parser = video_parser_of(codec_id);
  178.     if(parser == NULL){
  179.         return -1;
  180.     }

  181.     info.fourcc = parser->fourcc;
  182.     return parser->parser(flv_buffer, info);
  183. }

  184. //=========================================================

  185. static char adts[7] = {0xff, 0xf1};

  186. static int aac_parser(const char* flv_buffer, media_info& info){
  187.     int byte1 = ((int) flv_buffer[1]) & 0xff;
  188.     int byte2 = ((int) flv_buffer[2]) & 0xff;
  189.     int byte3 = ((int) flv_buffer[3]) & 0xff;
  190.     DWORD len = (byte1 << 16) | (byte2 << 8) | byte3;

  191.     int byte4 = ((int) flv_buffer[4]) & 0xff;
  192.     int byte5 = ((int) flv_buffer[5]) & 0xff;
  193.     int byte6 = ((int) flv_buffer[6]) & 0xff;
  194.     int byte7 = ((int) flv_buffer[7]) & 0xff;

  195.     info.dts = (byte7 << 24) | (byte4 << 16) | (byte5 << 8) | byte6;
  196.     info.pts = info.dts;

  197.     // flash only support 44k, 16bits aac
  198.     info.sample_rate = 44100;
  199.     info.bit_count = 16;
  200.     info.chans = (flv_buffer[11] & 0x01) ? 2 : 1;
  201.    
  202.     int type = ((int) flv_buffer[12]) & 0xff;
  203.     if(type == 0){
  204.         int byte13 = ((int) flv_buffer[13]) & 0xff;
  205.         int objType = ((byte13 & 0xf1) >> 3) - 1;

  206.         int byte14 = ((int) flv_buffer[14]) & 0xff;
  207.         int samplerate_indx = ((byte13 & 0x7) << 1 | (byte14 & 0x80) >> 7);
  208.         int chans = (byte14 & 0x71) >> 3;
  209.         // format of flash
  210.         assert(chans == 2 && samplerate_indx == 7);

  211.         adts[2] = (objType << 6) | (samplerate_indx << 2) | ((chans & 0x04) >> 2);
  212.         adts[3] = ((chans & 0x03) << 6);

  213.         return len + 11 + 4;
  214.     }else if(type == 1){
  215.         if(adts[2] == 0){
  216.             cs << "drop audio data, because of header is missing" << endl;
  217.             goto LABEL;
  218.         }
  219.         const static int adts_len = sizeof(adts);
  220.         info.length = len - 2 + adts_len;

  221.         info.buffer = (char *) malloc(info.length);
  222.         if(info.buffer == NULL){
  223.             return -1;
  224.         }
  225.         info.free = my_free;

  226.         assert(sizeof(int) == 4);
  227.         *((int *) &info.buffer[0]) = *((int *) &adts[0]);

  228.         info.buffer[3] |= (info.length & 0x1fff) >> 11;
  229.         info.buffer[4] = (info.length & 0x7ff) >> 3;
  230.         info.buffer[5] = (info.length & 0x07) << 5;
  231.         info.buffer[5] |= 0x1f;
  232.         info.buffer[6] = 0xfc;
  233.         memcpy((void *) &info.buffer[adts_len], &flv_buffer[13], len - 2);
  234. LABEL:
  235.         return len + 11 + 4;
  236.     }
  237.     return -1;
  238. }

  239. static flv_media_parser flv_aac_parser = {
  240.     mpeg4_aac,
  241.     aac_parser
  242. };

  243. static flv_media_parser* audio_parser_of(char codec_id){
  244.     if(codec_id == (char) 0xa0){
  245.         return &flv_aac_parser;
  246.     }
  247.     return NULL;
  248. }

  249. static int flv_audio_unpack(const char* flv_buffer, media_info& info){
  250.     char byte11 = flv_buffer[11] & 0xff;
  251.     char fmt = byte11 & 0xf0;

  252.     flv_media_parser* parser = audio_parser_of(fmt);
  253.     if(parser == NULL){
  254.         return -1;
  255.     }

  256.     info.fourcc = parser->fourcc;
  257.     return parser->parser(flv_buffer, info);
  258. }

  259. //=========================================================

  260. int FlvUnpack(const char* flv_buffer, media_info& info){
  261.     info.free = NULL;
  262.     info.buffer = NULL;
  263.     info.length = 0;

  264.     int n = -1;
  265.     char audio_or_video = flv_buffer[0];
  266.     if(audio_or_video == 0x09){
  267.         n = flv_video_unpack(flv_buffer, info);

  268.         if(n != -1){
  269.             if(FlvIsSpsFrame((BYTE *) flv_buffer, n)){
  270.                 FlvSaveSpsFrame((void *) flv_buffer, n);
  271.             }else if(FlvIsKeyFrame((BYTE *) flv_buffer, n)){
  272.                 FlvSaveKeyFrame((void *) flv_buffer, n);
  273.             }
  274.         }
  275.     }
  276.    
  277.     if(audio_or_video == 0x08){
  278.         n = flv_audio_unpack(flv_buffer,info);
  279.         if(n != -1){
  280.             if(FlvIsAacHeaderFrame((BYTE *) flv_buffer, n)){
  281.                 FlvSaveAacFrame((void *) flv_buffer, n);
  282.             }
  283.         }
  284.     }

  285.     return n;
  286. }

  287. BOOL FlvIsKeyFrame(BYTE* flv_buffer, int len){
  288.     if(len < 12 || flv_buffer[0] != 0x09){
  289.         return FALSE;
  290.     }
  291.         return (0x10 == (flv_buffer[11] & 0xf0));
  292. }

  293. BOOL FlvIsSpsFrame(BYTE* flv_buffer, int len){
  294.     if(len < 13 || flv_buffer[0] != 0x09){
  295.         return FALSE;
  296.     }
  297.         return (0 == (flv_buffer[12]));
  298. }

  299. BOOL FlvIsAacHeaderFrame(BYTE* flv_buffer, int len){
  300.     if(len < 13 || flv_buffer[0] != 0x08){
  301.         return FALSE;
  302.     }
  303.         return (0 == (flv_buffer[12]));
  304. }

  305. int FlvFrameLength(BYTE* flv_buffer, int len){
  306.     if(len < 4){
  307.         return -1;
  308.     }

  309.     int byte1 = ((int) flv_buffer[1]) & 0xff;
  310.     int byte2 = ((int) flv_buffer[2]) & 0xff;
  311.     int byte3 = ((int) flv_buffer[3]) & 0xff;
  312.     int length = (byte1 << 16) | (byte2 << 8) | byte3;

  313.     length += 11 + 4;
  314.     if(length <= len){
  315.         return length;
  316.     }
  317.     return -1;
  318. }

  319. DWORD FlvGetDts(BYTE* flv_buffer, int len){
  320.     if(len < 8){
  321.         return (DWORD) (-1);
  322.     }
  323.     int byte4 = ((int) flv_buffer[4]) & 0xff;
  324.     int byte5 = ((int) flv_buffer[5]) & 0xff;
  325.     int byte6 = ((int) flv_buffer[6]) & 0xff;
  326.     int byte7 = ((int) flv_buffer[7]) & 0xff;

  327.    DWORD st = (byte7 << 24) | (byte4 << 16) | (byte5 << 8) | byte6;
  328.    return st;
  329. }

  330. void FlvSetDts(UINT32 ts, void* buf, int len, BOOL zeroOffset){
  331.     int left = len;
  332.     char* pch = (char *) buf;
  333.     while(left > 0){
  334.         int n1 = pch[1] & 0xff;
  335.         int n2 = pch[2] & 0xff;
  336.         int n3 = pch[3] & 0xff;
  337.         int n = (n1 << 16) | (n2 << 8) | n3;

  338.         *((char*)pch + 4) = (unsigned char) (ts >> 16);
  339.             *((char*)pch + 5) = (unsigned char) (ts >> 8);
  340.             *((char*)pch + 6) = (unsigned char) ts;
  341.             *((char*)pch + 7) = (unsigned char) (ts >> 24);

  342.         if(zeroOffset){
  343.                 *((char*)pch + 13) = 0;
  344.                 *((char*)pch + 14) = 0;
  345.                 *((char*)pch + 15) = 0;
  346.         }
  347.         
  348.         pch += (n + 11 + 4);
  349.         left -= (n + 11 + 4);
  350.     }
  351.     assert(left == 0);
  352. }

  353. int FlvMediaType(const char* flv_buffer, int len){
  354.     if(len < 1){
  355.         goto LABEL;
  356.     }

  357.     if(flv_buffer[0] == 0x09){
  358.         return media_video;
  359.     }else if(flv_buffer[0] == 0x08){
  360.         return media_audio;
  361.     }
  362. LABEL:
  363.     assert(false);
  364.     return media_none;
  365. }

  366. int FlvTagBytes(int* head, int* tail){
  367.     if(head) *head = 11;
  368.     if(tail) *tail = 4;
  369.     return 15;
  370. }



  371. const static BYTE hdrflvout[] = {
  372.     0x46,0x4C,0x56,0x01,0x05,0x00,0x00,0x00,0x09,
  373.     0x00,0x00,0x00,0x00,
  374. };

  375. CFlvWrite::CFlvWrite(void){
  376.         m_bOk = FALSE;
  377.         m_hFile = NULL;
  378.     m_need_sps = TRUE;
  379.     m_need_kfrm = TRUE;
  380.     m_need_aach = TRUE;
  381.     m_base_tick_video = 0;
  382.     m_base_tick_audio = 0;
  383. }

  384. CFlvWrite::~CFlvWrite(void){
  385.         Close();
  386. }

  387. HRESULT CFlvWrite::Open(LPCTSTR szOutName, LPCTSTR szExtParam){
  388.         if(m_bOk)
  389.                 return S_OK;  //已经打开
  390.         m_bOk = FALSE;

  391.         m_hFile = _tfopen(szOutName, _T("wb"));
  392.         if( m_hFile <= 0)
  393.                 return E_FAIL;
  394.     fwrite(hdrflvout, sizeof(hdrflvout), 1, m_hFile);

  395.         m_bOk = TRUE;
  396.         return S_OK;
  397. }

  398. HRESULT CFlvWrite::Write(BYTE* ppData, int nLen){
  399.         SingleLock l(m_cs);
  400.     if(!m_bOk){
  401.                 return E_FAIL;
  402.     }

  403.     if(m_hFile == NULL){
  404.         ASSERT(FALSE);     
  405.         return E_FAIL;
  406.     }

  407.     int sps_len = 0;
  408.     char* sps_buf;
  409.     if(m_need_sps){
  410.         sps_len = FlvGetSpsFrame(sps_buf);
  411.     }

  412.     int keyframe_len = 0;
  413.     char* kfrm_buf;
  414.     if(m_need_kfrm){
  415.         keyframe_len = FlvGetLastKeyFrame(kfrm_buf);
  416.     }

  417.     int aac_len = 0;
  418.     char* aac_buf;
  419.     if(m_need_aach){
  420.         aac_len = FlvGetAacFrame(aac_buf);
  421.     }

  422.     while(nLen > 0){
  423.         int len = FlvFrameLength(ppData, nLen);
  424.         ASSERT(len != -1);

  425.         int type = FlvMediaType((const char *) ppData, len);
  426.         ASSERT(type != media_none);

  427.         if(type == media_audio){
  428.             if(m_need_aach){
  429.                 BOOL aach = FlvIsAacHeaderFrame(ppData, len);
  430.                 if(aach){
  431.                     m_need_aach = FALSE;
  432.                     FlvSetDts(0, ppData, len, FALSE);
  433.                     fwrite(ppData, 1, len, m_hFile);
  434.                     goto LABEL;
  435.                 }else if(aac_len){
  436.                     FlvSetDts(0, aac_buf, aac_len, FALSE);
  437.                     fwrite(aac_buf, 1, aac_len, m_hFile);
  438.                     m_need_aach = FALSE;
  439.                 }else{
  440.                     goto LABEL;
  441.                 }
  442.             }

  443.             ASSERT(!m_need_aach);
  444.             DWORD ts = FlvGetDts(ppData, len);
  445.             if(m_base_tick_audio == 0){
  446.                 m_base_tick_audio = ts;
  447.             }

  448.             FlvSetDts(ts - m_base_tick_audio, ppData, len, FALSE);
  449.             fwrite(ppData, 1, len, m_hFile);
  450.         }else{
  451.             BOOL sps = FlvIsSpsFrame(ppData, len);
  452.             if(sps){
  453.                 FlvSetDts(0, ppData, len, TRUE);
  454.                 fwrite(ppData, 1, len, m_hFile);
  455.                 m_need_sps = FALSE;
  456.                 goto LABEL;
  457.             }
  458.             
  459.             if(m_need_sps){
  460.                 if(sps_len == 0){
  461.                     goto LABEL;
  462.                 }
  463.                 FlvSetDts(0, sps_buf, sps_len, TRUE);
  464.                 fwrite(sps_buf, 1, sps_len, m_hFile);
  465.                 m_need_sps = FALSE;
  466.             }

  467.             DWORD ts = FlvGetDts(ppData, len);
  468.             if(m_base_tick_video == 0){
  469.                 m_base_tick_video = ts;
  470.             }

  471.             if(FlvIsKeyFrame(ppData, len)){
  472.                 m_need_kfrm = FALSE;
  473.             }else if(m_need_kfrm){
  474.                 if(keyframe_len == 0){
  475.                     goto LABEL;
  476.                 }

  477.                 FlvSetDts(0, kfrm_buf, keyframe_len, TRUE);
  478.                 fwrite(kfrm_buf, 1, keyframe_len, m_hFile);
  479.                 m_need_kfrm = FALSE;
  480.             }

  481.             FlvSetDts(ts - m_base_tick_video, ppData, len, FALSE);
  482.             fwrite(ppData, 1, len, m_hFile);
  483.         }
  484. LABEL:
  485.         ppData += len;
  486.         nLen -= len;
  487.     }

  488.     return S_OK;
  489. }


  490. HRESULT CFlvWrite::Close(){
  491.     if(m_hFile){
  492.                 fclose(m_hFile);
  493.     }

  494.     m_base_tick_video = m_base_tick_audio = 0;
  495.     m_need_aach = m_need_sps = m_need_kfrm = TRUE;
  496.         m_hFile = NULL;
  497.         m_bOk = FALSE;
  498.         return S_OK;
  499. }
复制代码

论坛徽章:
0
7 [报告]
发表于 2011-10-19 11:12 |只看该作者
貌似能实现无限长度的视频会议!Great!我需要!

论坛徽章:
0
8 [报告]
发表于 2011-10-19 11:51 |只看该作者
感谢各位,我们公司就是做网络会议的,不过我正在做的是会后的一个附加功能,提供会议的录制,要求对于会

中当中的视频数据,音频数据等。最后全部整合成一个文件,支持会后回放。我也就是一个新手,今年刚毕业

的,在这边也基本上给前辈打打下手,以后不懂得地方还得请各位多多关照!!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP