live555增强版--支持串流mp4格式

live555目前最新版(0.75)的mediaServer只支持".m4e"格式的Elementary Stream fie,但并不支持串流mp4封装格式的文件,要串流mp4格式的文件一般都是结合FFmpeg进行,但是代码量稍大,这里使用一种较为简单的方法实现对mp4封装格式文件的串流。

其具体思路如下图:

即我们预先对mp4文件进行处理,解析出各个流,并单独存储它们(解析工具用'mp4creator -extract='),然后将解析出来的H.264文件再进行串流处理(最新版的live555支持H.264的串流),客户端可用VLC或者FFmpeg的ffplay进行串流播放。

具体实现为只需在DynamicRTSPServer.cpp文件中添加如下实现代码:

else if((strcmp(extension, ".mp4") == 0) || (strcmp(extension, ".m4v") == 0))
  {
        NEW_SMS("MPEG-4 Video/Audio");
        // get the info about file
        char * command = (char *) malloc(150 * sizeof (char));
	    memset(command,0,150*sizeof(char));
        command = strcat(command, "mp4info  ");
        command = strcat(command, fileName);
        command = strcat(command, " >temp ");
        puts(command);
        system(command);
        /////////////////////////////parsing code/////////////////////////////////////////////
        FILE * fTemp = fopen("temp", "r"),*temp = NULL;
        if (fTemp != NULL)
		{
            char c, ext[4];
            ext[0] = '.';
            ext[1] = 't';
            ext[3] = '\0';
            char * Word = (char *) malloc(100 * sizeof (char));
			memset(Word,0,100 * sizeof(char));
            int flagLine = 0, lineCount = 0, flagWord = 0, wordCount = 0, i = 0, flagCodec = 0, streamCount = 1;
            while (!feof(fTemp))
			{
                if (lineCount != 3)
				{
                    c = getc(fTemp);
                }
                if (flagLine == 1)
				{
                    flagLine = 0;
                    if ((c > 48) && (c < 59)) {// get inside the stream numbers only ...
                        flagWord = 1;
                        while ((c != '\n') && (!feof(fTemp)))
						{
                            c = getc(fTemp);
                            if (flagWord == 1)
							{
                                i = 0;
                                while ((c != ' ') && (c != '\t') && (!feof(fTemp)))
								{
                                    Word[i] = tolower(c);
                                    i++;
                                    c = getc(fTemp);
                                }
                                Word[i] = '\0';

                                if ((strcmp("video", Word) == 0) || (strcmp("audio", Word) == 0)) 
								{
                                    flagCodec = 1;
                                    wordCount = 0;
                                    int i;
                                    for (i = 0; i < 100; i++)
									{
                                        Word[i] = '\n';
                                    }
                                    ext[2] = '0' + streamCount;
                                    strcpy(Word, "mp4creator -extract=");   
                                    Word[20] = streamCount + 48;
                                    Word[21] = ' ';
                                    Word[22] = '\0';
                                    Word = strcat(Word,fileName);
                                    puts(Word);

                                    command = strcpy(command, fileName);
                                    command = strcat(command, ext);
                                    temp = fopen(command,"r");
                                    if(temp == NULL)
									{
                                        env<< "creating files";
                                        system(Word);
                                    }
                                    puts(command);
                                    streamCount++;
                                }
                                if ((flagCodec == 1) && (wordCount == 1))
								{
                                    if (strcmp("h264", Word) == 0)
									{
                                    //    printf("error cant play H.264 files.");
                                    //    return 0;
										   NEW_SMS("H.264 Video");
										   OutPacketBuffer::maxSize = 100000; // allow for some possibly large H.264 frames
                                           sms->addSubsession(H264VideoFileServerMediaSubsession::createNew(env, command, reuseSource));
                                    }
                                }
                                if ((flagCodec == 1) && (wordCount == 2))
								{
                                    flagCodec = 0;
                                    printf("Flagged - %s  line: %d\n", Word, lineCount);
                                    ///////////////////////////////enter the code here////////////////////////////////
                                    if (strcmp("aac", Word) == 0)
									{
                                        puts("aac found");
                                        sms->addSubsession(ADTSAudioFileServerMediaSubsession
                                                ::createNew(env, command, reuseSource));
                                        puts(ext);
                                    } else if (strcmp("simple", Word) == 0)
									{
                                        puts("m4e found");
                                        sms->addSubsession(MPEG4VideoFileServerMediaSubsession
                                                ::createNew(env,command, reuseSource));
                                        puts(ext);
                                    } else if (strcmp("h264", Word) == 0) 
									{
                                        puts("m4e found");
                                        puts(ext);
                                    } else if (strcmp("amr", Word) == 0)
									{
                                        puts("amr found");
                                        puts(ext);
                                    }
                                }
                                flagWord = 0; ////////// the word flag is reset
                            }
                            if ((c == '\t') || (c == ' '))
							{
                                wordCount++;
                                flagWord = 1; // the word flag set for getting next word.
                            }
                        }
                        flagWord = 0;
                        wordCount = 0;
                        goto out;
                    }
                }
out:
                if (c == '\n') 
				{
                    lineCount++;
                    if (lineCount > 2)
					{
                        flagLine = 1;
                    }
                }

            }

        } else
		{
            printf("the file not found");
            return 0;
        }
	}


 

参考代码:http://sourceforge.net/projects/live555mp4/

附:

1.上述代码中用到两个工具程序mp4info.exe和mp4creator.exe,下载地址为:

http://download.csdn.net/detail/c_m_deng/4625514http://download.csdn.net/detail/c_m_deng/4625522

2.关于live555最新版(2012.10.04)的下载地址及VC++6.0编译参考前一篇文章

你可能感兴趣的:(流媒体)