3.25:
音视频同步
固定文件进行合并操作:
如果音频和视频长度不同,输出文件可能会被剪裁或缩短,以匹配较短的文件的长度。如果需要确保音频和视频长度匹配,请在合并之前对它们进行处理。
实时采集:
音视频同步采集,编码。(还有可能硬件设备性能差异)
时间戳同步:在合成音视频流时,确保为视频帧和音频帧正确设置时间戳(PTS,Presentation Time Stamp),以便接收端能够正确地按照时间戳将音频和视频进行同步播放
传输时延控制:在网络传输过程中,尽量减小音频和视频数据的传输时延,可以采用实时传输协议(如RTP/RTSP)来减少传输时延,或者采用缓冲机制来平衡传输时延和数据稳定性。
可能出现不同步的情况:
接收端:
网络延迟:在网络传输过程中,由于网络延迟的存在,可能导致音频和视频的到达时间有所不同,从而产生不同步的情况。
硬件设备性能差异:不同的硬件设备可能对音频和视频的处理速度有所不同,也可能导致不同步。
编解码器性能差异:不同的音频和视频编解码器可能对音视频数据的处理速度有所不同,也可能导致不同步。
时钟漂移:发送端和接收端的时钟存在微小的漂移,长时间传输可能会导致音频和视频的播放速度略有不同,从而导致不同步。
为了解决这些问题,通常需要综合考虑硬件设备、编码器、网络传输、时钟同步等因素,采取合适的策略来保证音频和视频的同步。这可能包括使用专门的同步算法、网络优化、硬件加速等手段来实现音视频同步。
个人猜测:传输时延应该可能性较小。
Mpegte流通过udp协议传输,是音频流和视频流分开传输,还是合并同步传输?
MPEG-TS(MPEG Transport Stream)通过UDP协议传输时,通常是将音频流和视频流分开传输的,而不是合并同步传输。这种方式被称为单独传输(Separate Transport)。在单独传输中,音频流和视频流会分别打包成不同的包,然后通过UDP协议进行传输。
每个包(Packet)都会携带一部分音频或视频数据,并且每个包都有自己的包头信息来标识其所属的流类型(音频流或视频流)。这样接收端在接收到数据包时可以根据包头信息将音频流和视频流进行分离和解码。
虽然音频流和视频流是分开传输的,但它们的时间戳信息会被同步,以确保在接收端能够正确地将音频和视频同步播放。接收端会根据时间戳信息对音频和视频进行缓冲和同步处理,以保证最终的播放效果是同步的。
总的来说,MPEG-TS通过UDP传输时一般会采用将音频流和视频流分开传输的方式,但在接收端会通过时间戳等机制来实现音视频的同步播放。这种分开传输的方式更有利于网络传输和解码处理,并且更容易实现跨平台兼容性。
将原始音视频数据压缩之后,压缩结果组成一个基本码流(ES),基本码流中是不是包含音视频压缩数据,并且是分开的,可不可以这样理解:一路为视频压缩数据,一路为音频压缩数据,是这样吗?
是的,您理解得很正确。将原始音视频数据进行压缩之后,压缩结果可以组成一个基本码流(Elementary Stream, ES)。基本码流中包含了音频和视频的压缩数据,并且这些数据是分开的,可以理解为一路是视频压缩数据,另一路是音频压缩数据。
在基本码流中,视频压缩数据和音频压缩数据是分开存放的,通常一个基本码流包含一路视频数据和一路音频数据。这种分开存放的方式有利于在传输过程中对音频和视频进行分开处理和解码,同时也有利于实现多种不同的音视频编码格式的兼容性。
因此,基本码流中包含了经过压缩处理的音频和视频数据,这些数据是分开存放的,便于在传输和解码过程中进行独立处理和再构造。
ES流:有三种,图像数据流,音频数据流,以及其他编码数据流。
PES流:PES流是ES流经过PES打包器处理后形成的数据流,在这个过程中完成了将ES流分组、打包、加入包头信息等操作(对ES流的第一次打包)。PES流的基本单位是PES包。
TS流:由定长的TS包组成(188字节),而TS包是对PES包的一个重新封装(到这里,ES经过了两层的封装) 。应用于相对有错环境下的传输与存储(如DVB中),其基本单位是TS包,长度固定188字节。日本的DVB-S广播系统采用192个字节的TS包,美国采用204个字节的TS包,多加了16个字节的前向纠错校验码(FEC)。
TS流的形成过程:
将原始音视频数据压缩之后,压缩结果组成一个基本码流(ES)。 对ES(基本码流)进行打包形成PES。 在PES包中加入时间戳信息(PTS/DTS)。 将PES包内容分配到一系列固定长度的传输包(TS Packet)中。 在传输包中加入定时信息(PCR)。 在传输包中加入节目专用信息(PSI) 。 连续输出传输包形成具有恒定比特率的MPEG-TS流。 TS流的解析过程,可以说是生成的逆过程:
从复用的MPEG-TS流中解析出TS包; 从TS包中获取PAT及对应的PMT(PSI中的表格); 从而获取特定节目的音视频PID; 通过PID筛选出特定音视频相关的TS包,并解析出PES; 从PES中读取到PTS/DTS,并从PES中解析出基本码流ES; 将ES交给解码器,获得压缩前的原始音视频数据。
从上面的定义可以分成三层来看TS/PS。
ES层 : 由单独的音频(如mp3),视频流(如h.264)组成基本的ES(Elementary Stream)。
PES层 : 将基本的ES按一定的规则(如H.264以AU)进行封装,并打上时间戳,组成PES。
TS/PS层: 将PES包进行切分后再封装成188bytes大小的TS包,
同时还将一些节目信息也封装成TS包(称为section), 两者共同组成TS层。
在TS 层 , TS头信息包含了节目时钟参考PCR(Program Clock Reference),
用于恢复出与编码端一致的系统时序时钟STC(System Time Clock)。
在PES层 , 在PES头信息里包含有表示时间戳PTS(Presentation Time Stamp)和
解码时间戳DTS(Decoding Time Stamp);
在ES 层 , 与同步有关的主要是视频缓冲验证VBV(Video Buffer Verifier),
用以防止解码器的缓冲器出现上溢或者下溢;
-----------
总结:是分开进行编码压缩的,然后进行包装传输。
那么就有可能是解码不同步,还有就是时钟不同步,进行解压缩,同步。
Mpegts流在接收端如何进行处理,如何同步处理。
Program Clock Reference是什么?
Program Clock Reference(PCR)是数字视频传输中的一个重要概念,主要用于同步音频和视频数据。在 MPEG 标准中,PCR 是一种时间基准,用于确保不同的音频、视频和其他数据流能够正确地同步播放。
具体来说,PCR 是一个时钟参考值,以90 kHz为单位,用于指示特定传输流中每个传输包的到达时间。通过 PCR,接收端可以根据不同数据包的到达时间来同步多个流,确保它们按照正确的顺序和时间间隔进行播放。
在 MPEG-2 系统中,PCR 通常会被插入到传输流的特定位置,以便接收端能够正确解析和处理数据。通过比较不同流中的 PCR 值,接收端可以调整播放速度,确保音频和视频之间的同步性。
总之,PCR 在数字视频传输中扮演着重要的角色,帮助确保多媒体数据流的同步性和一致性,以提供更流畅和高质量的播放体验。
-----------
音频和视频编解码器是什么,硬件还是程序?
音频和视频编解码器(Codec)既可以是硬件也可以是软件程序,具体取决于应用场景和实现方式。在计算机和移动设备中,通常会有专门的硬件编解码器(如处理器中集成的硬件编解码器),同时也会有基于软件的编解码器实现。
硬件编解码器是指通过硬件电路或芯片实现的编解码功能,通常能够提供高效的性能和低功耗。例如,手机、相机等设备中常常会有专门的视频编解码器芯片,用于实时处理视频数据。在计算机系统中,也会有一些专门的显卡或加速卡内置了视频编解码功能。
另一方面,软件编解码器是指通过软件程序来实现音频和视频的编解码功能。这种实现方式更灵活,可以在通用计算设备上运行,但通常会消耗更多的CPU资源。许多多媒体播放器、视频编辑软件和通信应用程序都会使用软件编解码器来处理音视频数据。
总的来说,音频和视频编解码器可以是硬件也可以是软件程序,不同的应用场景和需求会选择不同的实现方式来进行音视频数据的编解码处理。硬件编解码器通常具有高效性能和低功耗,而软件编解码器则更为灵活适用于通用计算设备。
AVFormatContext *pFormatCtx; //AVFormatContext结构体类型变量—
int i, videoindex;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame, *pFrameYUV;
uint8_t *out_buffer;
AVPacket *packet;
int y_size;
int ret, got_picture;
struct SwsContext *img_convert_ctx;
//判断是否打开文件
if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0) {
//打开输入视频文件
printf("Couldn't open input stream.\n");
return -1;
}
//判断是否找到流信息
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
//获取视频文件信息
printf("Couldn't find stream information.\n");
return -1;
}
//找到视频流并保存其索引
videoindex = -1;
for (i = 0; i < pFormatCtx->nb_streams; i++) {
//遍历streams数组,找到视频流在streams中的索引
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
videoindex = i;
break;
}
}
//如果索引还是-1,那么就是没有找到视频流
if (videoindex == -1) {
printf("Didn't find a video stream.\n");
}
pCodecCtx = pFormatCtx->streams[videoindex]->codec;//将视频流中的AVCodecContext赋给pCodecCtx
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);//查找解码器????
//查看是否能找到解码器
if (pCodec == NULL) {
printf("Codec not found.\n");
return -1;
}
//如果没有打开,返回-1
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
//打开解码器
printf("Could not open codec.\n");
return -1;
}
//打开文件并将指针fp指向文件
FILE *fp = fopen("output.txt", "wb+");
//将字符串格式化后写入到已经打开的文件中
fprintf(fp, "视频文件名:%s\n", filepath);
fprintf(fp, "封装格式:%s\n", pFormatCtx->iformat->name);
fprintf(fp, "码率:%d bps\n", pFormatCtx->bit_rate);
fprintf(fp, "编码方式:%s\n", pFormatCtx->streams[videoindex]->codec->codec->name);
fprintf(fp, "时长:%.2f s\n", (double)pFormatCtx->duration / 1000000);
fprintf(fp, "宽*高:%d*%d\n", pFormatCtx->streams[videoindex]->codec->width, pFormatCtx->streams[videoindex]->codec->height);
out_buffer = (unsigned char *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
avpicture_fill((AVPicture*)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
packet = (AVPacket *)av_malloc(sizeof(AVPacket));
基于FFmpeg实现视频的解封装和解编码(含FFmpeg环境搭建教学) - 知乎 (zhihu.com)
同步机制:
系统时钟STC:
编码器中有一个系统时钟(其频率是27MHz),
此时钟用来产生指示音视频的正确显示和解码的时间戳,
同时可用来指示在采样过程中系统时钟本身的瞬时值。
PCR(Program Clock Reference):
指示系统时钟本身的瞬时值的时间标签称为节目参考时钟标签(PCR)。
PCR的插入必须在PCR字段的最后离开复用器的那一时刻,
同时把27MHz系统时钟的采样瞬时值作为PCR字段插入到相应的PCR域。
它是放在TS包头的自适应区中传送.
I 帧(Intra coded frames):I 帧图像采用帧内编码方式,即只利用了单帧图像内的空间相关性,而没有利用时间相关性。I 帧使用帧内压缩,不使用运动补偿,由于 I 帧不依赖其它帧,所以是随机存取的入点,同时是解码的基准帧。
P 帧(Predicted frames):P 帧和 B 帧图像采用帧间编码方式,即同时利用了空间和时间上的相关性。P 帧图像只采用前向时间预测,可以提高压缩效率和图像质量,P 帧图像中可以包含帧内编码的部分,即 P 帧中的每一个宏块可以是前向预测,也可以是帧内编码。
B 帧(Bi-directional predicted frames):B 帧图像采用双向时间预测,可以大大提高压缩倍数。值得注意的是,由于 B 帧图像采用了未来帧作为参考,因此 MPEG-2 编码码流中图像帧的传输顺序和显示顺序是不同的。
也就是说,一个 I 帧可以不依赖其他帧就解码出一幅完整的图像,而 P 帧、B 帧不行。P 帧需要依赖视频流中排在它前面的帧才能解码出图像。B 帧则需要依赖视频流中排在它前面或后面的帧才能解码出图像。
3.28
miracast事情
sdl的分析
Tv本来就是接收端,用来接收连接与显示的。那么发送端如果能调用api那就容易,自己处理那就难。
目前找不到设备,需要先定位原因。
在一个sink端可以有办法将其变为source端发送数据吗?
在一些情况下,一台设备可能具有既能作为接收端(Sink)又能作为源端(Source)的能力,这种情况下称之为双向(bidirectional)支持。但通常情况下,设备被设计成只能扮演其中一种角色。
在一些特殊情况下,例如某些设备提供了软件更新或者特殊设置,可能会允许用户将接收端设备转变为源端设备。但这种情况并不常见,且需要设备的制造商提供相应的支持。
在一般情况下,如果一个设备被设计成只能作为接收端(Sink),那么通常是无法通过简单的设置或软件更新来改变其角色,因为这涉及到硬件和软件设计的差异。
miracast
Wifi display(基于wifi direct直连技术)
安卓手机默认有source端的api,只是没有暴露出来给开发者,这也是我们在Google开发者文档看不到的原因,我们如果想要调用,需要通过反射的方式(有技术实现难度,而且各个手机厂商的api有可能被定制化了)。
【安卓】安卓设备实现wifi display解决方案_wifidisplay安卓版-CSDN博客
还有一个问题,网络与wifi不能同时开启,如果使用miracast wifi直连的方式也许可以解决。
之前当我调试时就老是有问题,原因就是网线与wifi一块开启了(没办法,程序需要连wifi)。
Wifi和热点好像也不能同时开启。
但是今天我进行测试,发现网线与wifi是可以同时连接的。
但是有时候不能持久,一会儿过后,只剩下wlan的IP:
等于说,的的确确的是ethernet连接与wifi连接只能存在一个啊!!!!
开热点时候也是一样,不一会儿ethernet就会断线。
只开启wifi与热点我没法得出结论啊,没有显示屏!!!只有破板子,妈的。
-------------------------
miracast的server(source)-push 和client(sink)-pull互动模式是什么?
Miracast 是一种无线显示技术,它允许用户将设备(如手机、平板电脑、笔记本电脑)的屏幕内容通过无线连接投射到支持 Miracast 的显示设备(如电视、投影仪)上。在 Miracast 中,有两种互动模式:Server (Source)-Push 和Client (Sink)-Pull。
Server (Source)-Push 模式:
在 Server-Push 模式中,源设备(如手机或笔记本电脑)负责推送屏幕内容到目标显示设备(如电视)。源设备发送视频和音频数据流到接收设备,而接收设备仅负责接收和展示这些数据。此时,源设备控制着数据的传输和展示,而接收设备只是 passively 接收并显示。
Client (Sink)-Pull 模式:
在 Client-Pull 模式中,显示设备(如电视或投影仪)发起连接请求,请求源设备(如手机或笔记本电脑)推送屏幕内容。显示设备会向源设备发送一个连接请求,请求源设备开始推送屏幕内容。源设备会响应这个请求,并将屏幕内容推送到显示设备上进行展示。
总体来说,在 Miracast 技术中,Server-Push 模式和Client-Pull 模式提供了不同的连接方式,让用户可以根据具体需求选择合适的互动模式来进行屏幕投射操作。这些模式的选择通常取决于设备之间的关系以及用户希望谁来控制和发起投射操作。
----------
wifidisplay 的发送端与接收端设备有什么区别?
在 WiFi Display 技术中,通常会涉及到发送端(源设备)和接收端(显示设备),它们在功能和角色上有一些区别:
发送端(源设备):
功能:发送端通常是指启动屏幕镜像或投射的设备,它负责将自身屏幕内容发送到接收端进行显示。
设备类型:发送端可以是手机、平板电脑、笔记本电脑等具备 WiFi Display 功能的设备。
操作:发送端负责将屏幕内容编码并通过 WiFi 连接发送到接收端,控制屏幕内容的传输和显示。
接收端(显示设备):
功能:接收端通常是指接收并显示来自发送端的屏幕内容的设备。
设备类型:接收端可以是电视、投影仪等支持 WiFi Display 的显示设备。
操作:接收端负责接收发送端传输过来的数据流,并将其解码显示在屏幕上。
主要的区别在于发送端和接收端的功能和设备类型。发送端是主动发起屏幕镜像或投射的设备,负责将屏幕内容发送到接收端;而接收端则被动接收发送端的数据流,并将其显示在屏幕上。两者协同工作,实现了无线投射和屏幕镜像的功能。
接上例,两者的实现代码一样吗,可不可以使显示设备变为发送端?
在实际的场景中,发送端和接收端的实现代码通常会有所不同,因为它们需要处理不同的操作和功能。
发送端的实现代码通常涉及以下功能:
屏幕内容的捕获和编码
与接收端建立连接和数据传输
控制传输过程以及可能的交互操作
而接收端的实现代码通常包括以下功能:
接收来自发送端的数据流
数据解码和显示
响应发送端的控制指令(如果有)
因此,虽然两者都涉及无线投射技术,但实现代码会因为功能差异而不同。
至于将显示设备变为发送端,理论上是可能的,但这通常需要硬件设备支持,并且需要相应的软件和驱动程序来实现。一些专门设计用于这一目的的设备可能会允许用户将显示设备作为发送端使用,但通常普通的显示设备并不具备这样的功能。因此,一般情况下,普通的显示设备并不能直接变为发送端,除非设备本身具备相应的功能和支持。
目前还有一个问题,那就是不知道连接的问题还是视频解析的问题。视频解析3秒的话,那么黑屏事件延长肯定就是连接时间的问题,有时连接快,有时连接慢(这个是没办法的)。
有没有可能把重连方式改为不重新连接。
重新回到之前的网络状态的功能。
4.11
先看看如果只是播放,然后按键,会不会卡顿,如果不会,那就证明播放没问题。竟然真的会卡顿,但是本来就没有进行连接啊。
多次测试,发现按键没什么影响,获取后进行线程的传输就有问题了。
那么就证明确实是线程的问题。
后来发现不是线程的影响,而是蓝牙遥控影响的随心屏播放。
----------------------
原因是什么,现象是蓝牙连接不行,不连状态好一些。
连接其他wifi传输:
就算是很小的视频,10多M,还是卡。感觉不太像是网络的原因啊。但是用812板子近距离就不那么卡。
到底是什么原因呢?测试的目的就是要测试在其他的wifi情况下会不会有卡顿?来验证是否是蓝牙的影响。至少要保证wifi路由器的距离近,信号好。按理来说应该是不会卡顿的,但是事实是会卡顿。
在老板子里,测试,看看连接蓝牙后会不会卡顿。结果是会卡顿,但是是程序的问题,而不是蓝牙的影响。
4.15测试:
阀值,丢帧太频繁,一点点的不同步就开始丢帧。丢帧太频繁应该是自己指定了syn video,如果指定noframedrop呢?
不丢帧又会音视频不同步。syn ext,-按照官方文档来看应该是会自动丢帧的,除非你设置的为syn video需要自己丢帧。
那么可以试一下,当以syn ext,不进行丢帧呢?会不会不同步的更离谱。
syn video不进行丢帧,会不会不跳帧了。
实际结果:
syn ext 会默认丢帧,以便音视频同步。
syn ext -noframedrop,不丢帧,那么是否同步,需要多测试。竟然真的开始不同步了!!!
-sync video 应该是默认不丢帧的,相当于-noframedrop ,但是音频有怪声。
-sync video -framedrop 会进行丢帧,效果就是跳帧,给人卡顿的感觉。
当以视频为基准时,如果音频帧的PTS晚于视频帧的PTS,那么FFplay会加速播放音频,以保持音视频同步。然而,如果音频帧的PTS早于视频帧的PTS,那么FFplay会放慢音频播放速度,这可能会导致音频的音质下降。(属于这种情况)
当以音频为基准时,如果视频帧的PTS晚于音频帧的PTS,那么FFplay会丢弃这些视频帧,以保持音视频同步。相反,如果视频帧的PTS早于音频帧的PTS,那么FFplay会重复渲染上一帧视频,直到音频帧的PTS到达。这种策略可能会导致视觉上的掉帧现象。
这其实也是syn ext出现的现象。其实就是音频太早,只能丢视频帧。
那么能不能相差1秒内就不处理同步呢,
-----------
有缓冲区,-sync ext -framedrop 同步,再次进入时会有跑调音,但是会有卡顿现象,画面暂停,不连贯。
有缓冲区,-sync ext -noframedrop ,再次进入时会有跑调音,后续会正常。会有不同步的情况。画面会有花屏现象。
无缓冲区,-sync ext -framedrop ,同步,再次进入时会有跑调音,会有卡顿现象,画面暂停,不连贯。
无缓冲区,-sync ext -noframedrop同步,再次进入时会有跑调音,会有花屏现象。连贯。
不丢帧就有花屏,但是连贯。丢帧就不连贯。
有缓冲区有可能会不同步。
无论有无缓冲区,有无丢帧动作,刚进去的跑调音不可避免。
丢帧还是要进行丢帧的(以同步音视频)。缓冲区是不能要的,有可能是缓冲区太大了,确实如果可以调整可以试一下。
ffplay 丢帧策略:
https://www.jianshu.com/p/1b6ee4c60212
https://developer.baidu.com/article/details/3268454
https://www.zhihu.com/question/624148245
解码器线程并行处理视频帧或音频样本来实现的。
具体来说,FFmpeg 提供了一种称为解码器线程的机制,它允许开发人员指定在解码过程中要使用的线程数。这允许在多核处理器上利用多个核心进行并行解码,从而提高解码速度和效率。
不过需要注意的是,并非所有的解码器都支持多线程解码,因此实际的多线程性能取决于所使用的解码器以及解码的媒体格式。某些编解码器可能对多线程解码提供更好的支持,而另一些可能不太适合多线程解码。
-----------------------------
可不可以用老板子测试一下,连接wifi连哪儿呢,这边又没有可以连接的地方。可以这样试,只保留播放的,那么蓝牙一定不会影响啊。(需要看的是他的播放状态看会不会有卡顿,应该是不会卡顿的,如果卡顿那就是程序处理有漏洞) 但是蓝牙又连接不上,蓝牙模块???不懂。估计有可能是老板子没有支持蓝牙。
.测试蓝牙连接后,视频播放状态。
.测试通过wifi连接视频播放状态
.测试通过wifi连接视频播放,蓝牙连接控制下的播放状态。
在使用网线的情况下是不卡的!!!!!!!!!
还可以这样,都通过我的手机热点进行传输。
用电脑也行,电脑连接手机热点,客户端也是,然后电脑发送,客户端播放,看看卡不卡。
用手机做热点,播放会花屏。但是偶尔还是很流畅的。可能是信号问题,可能是程序处理不过来的问题,还有可能是手机问题!!!!!
接下来验证当蓝牙连接后会怎么样。
偶尔一两帧会好一些。
所以蓝牙 的影响还是很小的,主要还是程序的问题。
那么接下来直接使用板子进行验证:
客户端直接连接,看看花屏不花屏。
我还得确保一件事,板子中正在播放视频,一会看看里面有没有视频,没有的话那就复制个视频,然后直接进行播放,看看他视频传输怎么样。
结果是一旦连接上蓝牙就开始卡顿,而断开就没有这种情况。
或者可以这样,直接客户端程序不进行socket连接,让遥控器进行
结论是会有极少数情况下的确是会花屏(那么也就是说程序急需要进行优化,这是一定的!!!!!)
但是一旦连接上蓝牙就会出现严重的花屏,甚至屏幕卡死一两秒。
有没有其他的方式可以呢?android应用程序。网络包,除了c代码,还有没有其他的方式呢?果真,android程序也可。!!!
怎么蓝牙就会影响到呢?不会吧。
812接收连接,发送视频数据。客户端连接,接收视频数据。
应该不关发送端的事情啊,那么客户端经过验证也没有问题啊,你看抖音也不卡顿啊。
而且就算不用蓝牙 ,也还是会有卡顿情况,所以要赶快找到程序中的错误。
结论:需要梳理逻辑,找出卡顿原因,优化代码或逻辑。!!!!!!!
在随心屏上进行播放时,同样是连接zn812发送端,播放时就不卡。而且是高帧率的。
而在812 的demo板子上播放720分辨率的视频都卡。
电脑发送,通过路由器,网线
网线:
7414
7222
7279
7304
7355
7324
电脑发送,通过路由器,无线
wifi网络:360wifi
7411
7376
8018
7439
7300
7352
电脑发送,通过路由器,无线
2F-5G:
7346
7348
7242
7345
7334
7367
通过
通过812:
1022
1021
1025
1022
1022
1025
电脑连接客户端:也还会卡
7781
9722
7192
8827
6879
7315
网线会卡(812板子),无线会卡(随心屏),但是接收的数据包数量差异并不大。但是播放效果差异很大(有可能是因为连接的不是同一个路由器)。
如果同一板子,效果会怎么样?预期应该是不卡的,如果卡那就是数据发送太少。
结果就是不太卡,然后那就是换一个大数据的来试一下。数据量比较大的那种。
那么随心屏通过无线为何会那么卡呢?估计就是信号的确不好吧,但是通过接收数据挺多的数据包啊。反而使用zn812热点接收数据包不多,但是不会卡。使用电脑发送,客户端开热点,卡顿。(完全没有头绪到底是为什么)
首先还是需要整体把握,否则怎么查看,在正确的位置进行添加代码,并且能够调用新添的c程序代码。
至于 SDLActivity 如何调用底层库来播放视频,大致流程如下:#####
初始化 SDL:SDLActivity 在其 onCreate() 方法中会初始化 SDL 库,包括创建窗口、初始化音频、视频子系统等。
初始化底层视频播放器:在 SDL 初始化完成后,你可以调用底层的 C/C++ 函数来初始化视频播放器,比如初始化 FFmpeg 库、打开视频文件等。
解码和渲染视频帧:底层视频播放器会不断解码视频帧,并通过 SDL 提供的接口将视频帧渲染到屏幕上。
处理用户输入和事件:SDLActivity 会监听用户输入事件,比如触摸事件、键盘事件等,并将其传递给底层的 SDL 库。
清理工作:在应用退出或者 SDLActivity 销毁时,需要释放相关资源,包括关闭视频文件、释放 FFmpeg 相关的资源、销毁 SDL 窗口等。
总的来说,SDLActivity 作为一个提供了界面和事件处理的抽象层,负责管理 Android 应用的生命周期和用户交互,而底层的 C/C++ 代码则负责具体的视频播放功能。通过 SDL 提供的接口,这两部分可以很好地结合在一起,实现音视频播放功能。
4.16
ffmpeg参数含义:
-re
在实时模式和非实时模式下,FFmpeg 处理输入文件的方式略有不同:
实时模式(-re):
在实时模式下,FFmpeg 按照输入文件的本身帧率进行处理。
它会尽量保持处理速度与输入文件的播放速度一致,以便实现实时传输。
实时模式适用于需要模拟实时流传输的场景,如视频会议、实时监控、直播等。
非实时模式:
在非实时模式下,FFmpeg 会尽可能快地处理整个文件,而不考虑其本身的时间戳。
FFmpeg 会尽可能地利用系统资源,以最快的速度处理输入文件。
非实时模式适用于一般的视频处理任务,如转码、剪辑、过滤等,不需要考虑实时性要求。
因此,实时模式和非实时模式的主要区别在于处理速度的优先级。实时模式更关注于保持视频处理速度与输入文件的播放速度一致,而非实时模式则更关注于尽可能快地处理整个文件。
#########实时模式就好比抖音的直播功能,非实时就好比抖音的视频功能。
-----------------------
一些测试的结果:
通过wifi路由器中转的方式,电脑无线发送,板子无线接收。
假如通过直连呢?网线呢?网线的方式不行,计算机拒绝访问,无法连接。
直连的情况,是不卡的,但是一旦按键,有定义的就会卡顿,也许真的就是线程太多影响力。
帧率不能太高。25帧也不算很卡,就是音视频同步有点不和谐。
所以极有可能就是距离导致的网络信号的问题,而在程序中又没有进行相应的处理,所以就会有时卡顿,有时不卡顿。
然后就是可以用发送端的板子进行测试了。发现media里播放的视频质量虽然不是太好,但是整体还算流畅,不会太过于卡顿。(好像是低帧率的)
然后可以优化按键事件了,用队列去实现。应该还是可以的。不错。
资料:
.m3u8
服务器将视频流进行切片,生成m3u8文件【播放列表文件,用于记录媒体片段的信息,包括它们的 URL 地址、时长等,播放器(如流媒体播放器或浏览器)会根据 .m3u8 文件中指定的媒体片段的 URL 地址去获取这些片段,并将它们按顺序加载和播放,从而实现整个流媒体的播放。】
服务器视频网址:
http://www.rmp-streaming.com/media/big-buck-bunny-360p.mp4
一些资料:
如果在 ijkplayer 里 在出现音视频不同步,那么很可能就是视频的码率或者帧率太高,可以尝试使用使用 framedrop 丢帧或者开启硬解码支持。
为什么我的视频出现黑边?
这个问题其实就是常识性问题,面对不同尺寸不同分辨率的平台,视频显示是根据你给定的 Surface 大小去进行显示,所以你可以选择使用拉伸、裁剪、适应高度、适应宽度等不同布局。
---
一些测试时可能遇到的问题:
有时候客户端再次进行连接发现提示了ip,但是没有画面:这是通过mac地址连接的,连接上应该就是有画面的。只要发送端正常开启。需要稍微等一下。
可能的原因:
1.发送端程序未正确启动;
2.客户端已经连接上热点,但是由于发送程序未正确启动看不到客户端画面,然后客户端未退出,仅仅只是重新运行发送端程序。
zn812是开着的,但是客户端却连接不上,显示:出了点问题,该应用已取消选择设备的请求。 估计是连接的已经被占用了。 但是用无线网卡竟然能够连接上!!!后面没有遇到过这样的问题了,最有可能就是连接被占用。
重启后也会出现该应用已取消选择设备的请求的弹框,但是还是连接上了,接收视频并显示了。
正确做法:
客户端程序退出,将发送端程序先打开,然后再用客户端去连接。
探索,资料:
在Android中进行视频播放,通常使用的是MediaPlayer类或者更先进的ExoPlayer库。
MediaPlayer类:MediaPlayer是Android提供的基本的多媒体播放器类,可以用于播放音频和视频文件。它可以处理本地文件、网络文件、以及流媒体等不同的数据源。使用MediaPlayer类可以比较容易地实现简单的视频播放功能,但它的功能相对较为有限。
ExoPlayer库:ExoPlayer是Google开发的一个灵活、可扩展的多媒体播放库,它提供了更高级的功能和更好的性能。ExoPlayer支持更广泛的媒体类型和格式,具有更好的网络适应性和更低的延迟。它还提供了更丰富的控制接口,可以满足更复杂的应用需求,比如实现自定义播放器UI、实现自定义的播放策略等。
在使用MediaPlayer或ExoPlayer进行视频播放时,通常需要先进行视频文件的解析,以获取视频的元数据信息、视频流数据等。解析过程主要涉及视频格式的识别、媒体容器的解析、音视频流的分离等操作。这些解析过程可以由MediaPlayer或ExoPlayer内部完成,开发者通常无需直接处理。
总的来说,Android中的视频播放通常使用MediaPlayer类或者ExoPlayer库,它们都会内部完成视频文件的解析工作。