【流媒体】RTMPDump—Download(接收流媒体信息)
创始人
2024-10-17 13:41:27
0

目录

RTMP协议相关:
【流媒体】RTMP协议概述
【流媒体】RTMP协议的数据格式
【流媒体】RTMP协议的消息类型
【流媒体】RTMPDump—主流程简单分析
【流媒体】RTMPDump—RTMP_Connect函数(握手、网络连接)
【流媒体】RTMPDump—RTMP_ConnectStream(创建流连接)
【流媒体】RTMPDump—Download(接收流媒体信息)
【流媒体】RTMPDump—AMF编码
【流媒体】基于libRTMP的H264推流器

参考雷博的系列文章(可以从一篇链接到其他文章):
RTMPdump 源代码分析 1: main()函数

在进行流连接之后,还可以进行传输过来数据的下载,执行这一功能的函数是Download(),其中使用RTMP_Read()读取数据,随后使用fwrite写入文件。写入文件通常是FLV格式,如果没有指定这个file,则会默认写到stdout

int Download(RTMP * rtmp,		// connected RTMP object 	FILE * file, uint32_t dSeek, uint32_t dStopOffset, double duration, int bResume, char* metaHeader, uint32_t nMetaHeaderSize, char* initialFrame, int initialFrameType, uint32_t nInitialFrameSize, int nSkipKeyFrames, int bStdoutMode, int bLiveStream, int bRealtimeStream, int bHashes, int bOverrideBufferTime, uint32_t bufferTime, double* percent)	// percentage downloaded [out] { 	int32_t now, lastUpdate; 	int bufferSize = 64 * 1024; 	char* buffer; 	int nRead = 0; 	off_t size = ftello(file); 	unsigned long lastPercent = 0;  	rtmp->m_read.timestamp = dSeek;  	*percent = 0.0;  	if (rtmp->m_read.timestamp) 	{ 		RTMP_Log(RTMP_LOGDEBUG, "Continuing at TS: %d ms\n", rtmp->m_read.timestamp); 	}  	if (bLiveStream) 	{ 		RTMP_LogPrintf("Starting Live Stream\n"); 	} 	else 	{ 		// print initial status 		// Workaround to exit with 0 if the file is fully (> 99.9%) downloaded 		if (duration > 0) 		{ 			if ((double)rtmp->m_read.timestamp >= (double)duration * 999.0) 			{ 				RTMP_LogPrintf("Already Completed at: %.3f sec Duration=%.3f sec\n", 					(double)rtmp->m_read.timestamp / 1000.0, 					(double)duration / 1000.0); 				return RD_SUCCESS; 			} 			else 			{ 				*percent = ((double)rtmp->m_read.timestamp) / (duration * 1000.0) * 100.0; 				*percent = ((double)(int)(*percent * 10.0)) / 10.0; 				RTMP_LogPrintf("%s download at: %.3f kB / %.3f sec (%.1f%%)\n", 					bResume ? "Resuming" : "Starting", 					(double)size / 1024.0, (double)rtmp->m_read.timestamp / 1000.0, 					*percent); 			} 		} 		else 		{ 			RTMP_LogPrintf("%s download at: %.3f kB\n", 				bResume ? "Resuming" : "Starting", 				(double)size / 1024.0); 		} 		if (bRealtimeStream) 			RTMP_LogPrintf("  in approximately realtime (disabled BUFX speedup hack)\n"); 	}  	if (dStopOffset > 0) 		RTMP_LogPrintf("For duration: %.3f sec\n", (double)(dStopOffset - dSeek) / 1000.0);  	if (bResume && nInitialFrameSize > 0) 		rtmp->m_read.flags |= RTMP_READ_RESUME; 	rtmp->m_read.initialFrameType = initialFrameType; 	rtmp->m_read.nResumeTS = dSeek; 	rtmp->m_read.metaHeader = metaHeader; 	rtmp->m_read.initialFrame = initialFrame; 	rtmp->m_read.nMetaHeaderSize = nMetaHeaderSize; 	rtmp->m_read.nInitialFrameSize = nInitialFrameSize;  	buffer = (char*)malloc(bufferSize);  	now = RTMP_GetTime(); 	lastUpdate = now - 1000; 	do 	{ 		// 读取信息 		nRead = RTMP_Read(rtmp, buffer, bufferSize); 		//RTMP_LogPrintf("nRead: %d\n", nRead); 		if (nRead > 0) 		{ 			// 将数据写入到file当中,FLV格式 			// 如果这个file没有指定,默认是stdout 			if (fwrite(buffer, sizeof(unsigned char), nRead, file) != 				(size_t)nRead) 			{ 				RTMP_Log(RTMP_LOGERROR, "%s: Failed writing, exiting!", __FUNCTION__); 				free(buffer); 				return RD_FAILED; 			} 			size += nRead;  			//RTMP_LogPrintf("write %dbytes (%.1f kB)\n", nRead, nRead/1024.0); 			if (duration <= 0)	// if duration unknown try to get it from the stream (onMetaData) 				duration = RTMP_GetDuration(rtmp);  			if (duration > 0) 			{ 				// make sure we claim to have enough buffer time! 				if (!bOverrideBufferTime && bufferTime < (duration * 1000.0)) 				{ 					bufferTime = (uint32_t)(duration * 1000.0) + 5000;	// extra 5sec to make sure we've got enough  					RTMP_Log(RTMP_LOGDEBUG, 						"Detected that buffer time is less than duration, resetting to: %dms", 						bufferTime); 					RTMP_SetBufferMS(rtmp, bufferTime); 					RTMP_UpdateBufferMS(rtmp); 				} 				*percent = ((double)rtmp->m_read.timestamp) / (duration * 1000.0) * 100.0; 				*percent = ((double)(int)(*percent * 10.0)) / 10.0; 				if (bHashes) 				{ 					if (lastPercent + 1 <= *percent) 					{ 						RTMP_LogStatus("#"); 						lastPercent = (unsigned long)* percent; 					} 				} 				else 				{ 					now = RTMP_GetTime(); 					if (abs(now - lastUpdate) > 200) 					{ 						RTMP_LogStatus("\r%.3f kB / %.2f sec (%.1f%%)", 							(double)size / 1024.0, 							(double)(rtmp->m_read.timestamp) / 1000.0, *percent); 						lastUpdate = now; 					} 				} 			} 			else 			{ 				now = RTMP_GetTime(); 				if (abs(now - lastUpdate) > 200) 				{ 					if (bHashes) 						RTMP_LogStatus("#"); 					else 						RTMP_LogStatus("\r%.3f kB / %.2f sec", (double)size / 1024.0, 						(double)(rtmp->m_read.timestamp) / 1000.0); 					lastUpdate = now; 				} 			} 		} 		else 		{ #ifdef _DEBUG 			RTMP_Log(RTMP_LOGDEBUG, "zero read!"); #endif 			if (rtmp->m_read.status == RTMP_READ_EOF) 				break; 		}  	} while (!RTMP_ctrlC && nRead > -1 && RTMP_IsConnected(rtmp) && !RTMP_IsTimedout(rtmp)); 	free(buffer); 	if (nRead < 0) 		nRead = rtmp->m_read.status;  	/* Final status update */ 	if (!bHashes) 	{ 		if (duration > 0) 		{ 			*percent = ((double)rtmp->m_read.timestamp) / (duration * 1000.0) * 100.0; 			*percent = ((double)(int)(*percent * 10.0)) / 10.0; 			RTMP_LogStatus("\r%.3f kB / %.2f sec (%.1f%%)", 				(double)size / 1024.0, 				(double)(rtmp->m_read.timestamp) / 1000.0, *percent); 		} 		else 		{ 			RTMP_LogStatus("\r%.3f kB / %.2f sec", (double)size / 1024.0, 				(double)(rtmp->m_read.timestamp) / 1000.0); 		} 	}  	RTMP_Log(RTMP_LOGDEBUG, "RTMP_Read returned: %d", nRead);  	if (bResume && nRead == -2) 	{ 		RTMP_LogPrintf("Couldn't resume FLV file, try --skip %d\n\n", 			nSkipKeyFrames + 1); 		return RD_FAILED; 	}  	if (nRead == -3) 		return RD_SUCCESS;  	if ((duration > 0 && *percent < 99.9) || RTMP_ctrlC || nRead < 0 		|| RTMP_IsTimedout(rtmp)) 	{ 		return RD_INCOMPLETE; 	}  	return RD_SUCCESS; } 

相关内容

热门资讯

如何限制安卓系统流量,安卓系统... 手机流量用得飞快,是不是你也觉得每个月的账单让人心疼呢?别急,今天就来教你怎么限制安卓系统的流量,让...
国内各安卓系统对比,性能与特色... 你有没有发现,手机里的安卓系统就像是个大花园,各种花儿争奇斗艳,各有各的特色呢?今天,就让我带你走进...
安卓车机查看系统,安卓车机系统... 你有没有发现,现在开车的时候,车机系统简直就像是个贴心的智能小助手呢?没错,就是那个安卓车机查看系统...
安卓禁止进系统设置,深度解析禁... 你有没有发现,最近你的安卓手机有点儿“小脾气”呢?它突然变得不那么听话了,你想进系统设置调整却发现门...
小米3安卓系统下载,畅享极致性... 亲爱的手机控们,你是否曾为拥有一款性能卓越、价格亲民的智能手机而心动?小米3,这款曾经风靡一时的国产...
柯米克加安卓系统,智能出行新体... 你知道吗?最近汽车界可是掀起了一股新潮流,那就是柯米克加安卓系统。这可不是什么小打小闹,而是实实在在...
印度pc版安卓系统,PC版安卓... 你有没有想过,当印度这个古老而神秘的国度,与现代化的安卓系统相遇,会擦出怎样的火花呢?今天,就让我带...
安卓相册变苹果系统,一次系统切... 你有没有发现,你的安卓手机相册突然变成了苹果系统的样子?是不是有点懵圈,不知道怎么操作了?别急,今天...
安卓 x windows系统下... 你有没有想过,为什么你的手机里装的是安卓系统,而电脑上却是Windows系统呢?这两种操作系统各有千...
安卓系统文件分析其他,构建与维... 你有没有想过,你的安卓手机里那些看似杂乱无章的文件,其实隐藏着不少秘密呢?今天,就让我带你一起揭开安...
安卓系统导航启动慢,深度剖析原... 手机里的安卓系统导航启动慢,是不是让你感觉像是在等蜗牛爬行?别急,今天就来给你揭秘这个让人头疼的小问...
如何在win系统安装安卓系统,... 你是不是也对在Windows系统上安装安卓系统感兴趣呢?想象一边享受着Windows的强大功能,一边...
安卓系统 语言设置在哪 你有没有发现,手机里的安卓系统有时候就像一个神秘的宝盒,里面藏着各种各样的秘密?今天,我就要来揭秘一...
安卓转到苹果手机系统,系统切换... 你终于下定决心要从安卓转到苹果手机系统啦!这可是个大转变呢,就像从熟悉的老朋友跳到了一个全新的世界。...
安卓系统女生跑步图标,活力与时... 你有没有发现,每次打开安卓手机,在运动应用里看到那个跑步的图标,是不是瞬间感觉活力四溢,仿佛自己已经...
安卓 替换系统相机,打造个性化... 你有没有想过,你的安卓手机相机功能其实可以大变身呢?没错,就是那个我们每天拍照、录视频的相机,今天就...
华为手环app安卓系统,华为手... 你有没有发现,最近你的手腕上多了一道亮丽的风景线——华为手环?这款智能穿戴设备不仅外观时尚,功能强大...
安卓系统怎么连海马,开启智能生... 你有没有想过,你的安卓手机怎么和海马智能音响连接呢?别急,今天就来手把手教你如何轻松搞定这个连接大法...
安卓手表系统下载软件,轻松拓展... 你有没有发现,最近安卓手表越来越受欢迎了呢?这不,手上的安卓手表已经成了时尚的象征,而且功能强大到让...
安卓系统sd卡清理,提升手机性... 手机里的安卓系统是不是越来越慢了?是不是觉得SD卡里的东西越来越多,清理起来头都大了?别急,今天就来...