我想监视和记录伪终端设备 /dev/pts/12 (用于调试目的),即我想查看写入终端的内容,并且我不希望任何使用终端的进程注意到。
显而易见的解决方案
cat /dev/pts/1
cat </dev/pts/1
Run Code Online (Sandbox Code Playgroud)
不起作用:充其量,它似乎只捕获击键。
换句话说,我想要类似 script -t file.timings typescript 的输出;但我还需要击键。Reptyr -l $PID 是另一个可能有帮助的程序:它将进程 $PID 的输出重定向到另一个 /dev/pts 或管道。
我正在将 mpeg4 视频混合到 avi 容器。视频流约为 4fps,因此我设置AVCodecContext time_base为 1/4 ( formatContext->streams[0]->codec->time_base...) ,然后重新调整每个帧时间戳,因为原始时间戳以毫秒为单位。我将结果值分配给数据包pts和dts。
当我用 VLC 播放此 avi 时,视频不流畅,并且反复收到以下消息:
avcodec 错误:视频延迟超过 5 秒 -> 丢帧(计算机太慢?)
上面的pts/dts计算有问题吗?
下表演示了时间戳如何重新缩放(原始->重新缩放)
stream: 0 1329471005111->1
stream: 0 1329471005348->2
stream: 0 1329471005588->3
stream: 0 1329471005828->4
stream: 0 1329471006068->5
stream: 0 1329471006308->6
stream: 0 1329471006551->7
stream: 0 1329471006788->8
stream: 0 1329471007028->9
stream: 0 1329471007268->10
stream: 0 1329471007508->11
stream: 0 1329471007748->12
stream: 0 1329471007988->13
stream: 0 1329471008228->14
stream: 0 1329471008468->15
Run Code Online (Sandbox Code Playgroud) 我已经看到许多关于视频 PTS 值不是从零开始的问题,或者询问如何让它们从零开始。我知道使用 ffmpeg 我可以做一些类似ffmpeg -i <video> -vf="setpts=PTS-STARTPTS" <output>的事情来解决这种事情
然而这是我的理解是PTS值不具有在零开始。例如,如果您加入了直播,那么它可能已经持续了一个小时,并且 PTS 已经在 3600000+ 左右,但是您的视频播放器忠实地显示了一切。因此,如果我有意创建一个 PTS 值从当前挂钟时间开始的视频,我希望不会有问题。
我想使用 ffmpeg 发送实时流,但将当前时间嵌入到流中。这既可用于流直播时的延迟计算,也可用于稍后确定流最初播出的时间。根据我对 PTS 的理解,像这样简单的事情应该可行:
ffmpeg -i video.flv -vf="setpts=RTCTIME" rtmp://<output>
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试此操作时,ffmpeg 输出以下内容:
frame= 93 fps= 20 q=-1.0 Lsize= 9434kB time=535020:39:58.70 bitrate= 0.0kbits/s speed=1.35e+11x
Run Code Online (Sandbox Code Playgroud)
注意“时间”、比特率(0.0kbits)和速度(135000000000x !!!)的极大值
起初我认为问题可能是我的时基,所以我尝试了以下方法:
ffmpeg -i video.flv -vf="settb=1/1K,setpts=RTCTIME/1K" rtmp://<output>
Run Code Online (Sandbox Code Playgroud)
这将所有内容都以毫秒为单位(1 PTS = 1 ms),但我遇到了同样的问题(大量时间、零比特率和大量速度)
我对 PTS 有什么误解吗?是否不允许从非零值开始?还是我只是做错了什么?
在查看@Gyan 的回答后,我像这样格式化了我的命令:
ffmpeg -re -i video.flv -vf="settb=1/1K, setpts=(RTCTIME-RTCSTART)/1K" -output_ts_offset $(date +%s.%N) rtmp://<output>
Run Code Online (Sandbox Code Playgroud)
这样 PTS 值将匹配到“自流开始以来的毫秒数”,并且会被流的开始时间偏移(理论上使 PTS = 服务器上的时间戳)
这看起来编码更好: …
我有一系列视频,我正在将这些视频转换.mov为.ts,然后为其创建 HLS 播放列表。我能够找出任何给定视频的音频和视频流的结束点,并在转换序列中的后续视频时应用该结束(累积)偏移量。例如:
ffmpeg -y -i 1.mov \
-filter:a "asetpts=PTS-STARTPTS+367534" \
-filter:v "setpts=PTS-STARTPTS+363000" \
-codec:v libx264 -crf 18 -preset veryfast \
-acodec aac -muxdelay 0 1.ts
Run Code Online (Sandbox Code Playgroud)
这有效,但需要相当数量的 CPU。我希望能够理想地复制视频/音频流。有什么方法可以在.ts不重新编码整个文件的情况下为文件的音频/视频流应用统一的 pts 偏移量?
我正在尝试编写一个方法,在查询时提供下一帧和显示时间戳.代码目前看起来像这样:
while( getNextFrame(image, pts) )
{
// show current image
drawImage(currentImage);
sleep(pts);
currentImage = image;
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我一直在关注Dranger教程,但是为了可靠地获取帧的PTS值而停滞不前(http://www.dranger.com/ffmpeg/tutorial05.html).返回的PTS值始终为0.
此外,get_buffer()已被弃用,所以我现在使用该get_buffer2()方法设置全局pts值.但是,该release_buffer方法也已被弃用,我似乎无法找到它的替代品.这让我相信教程中列出的方法可能不再是完成此任务的最佳方法.
简而言之,使用最新的ffmpeg,可靠地获取帧pts值的最佳方法是什么?
我正在尝试同步从MP4视频解码的帧.我正在使用FFMPEG库.我已经解码并存储了每个帧,并在OPENGL平面上成功显示了视频.
我在骑车穿过车架之前就开始了一个计时器; 目的是正确同步视频.然后我将每帧的PTS与此计时器进行比较.我在解码过程中存储了从数据包接收的PTS.
我的应用程序中显示的内容似乎没有达到我期望的速度.它比媒体播放器中的原始视频文件播放速度更快.
我对FFMPEG和一般的编程视频缺乏经验.我是以错误的方式解决这个问题吗?
这是我试图做的一个例子
FrameObject frameObject = frameQueue.front();
AVFrame frame = *frameObject.pFrame;
videoClock += dt;
if(videoClock >= globalPTS)
{
//Draw the Frame to a texture
DrawFrame(&frame, frameObject.m_pts);
frameQueue.pop_front();
globalPTS = frameObject.m_pts;
}
Run Code Online (Sandbox Code Playgroud)
请注意我使用的是C++,Windows,Opengl,FFMPEG和VS2010 IDE
如何从 pts 和 time_base 或持续时间获取视频或 rtmp 流中帧的时间戳?多谢!
import av
def init_input(file_name):
global a
container = av.open(file_name)
a = container.duration
return container.decode(video=0)
url = "rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov"
stream1 = init_input(url)
for frame1 in stream1:
print(frame1.pts)
print(frame1.time_base)
Run Code Online (Sandbox Code Playgroud)
PS:frame.time与实际时间不正确
我有一个mov文件,我需要获得pts音频和视频流的结尾。我可以通过执行以下操作(手动)来做到这一点:
ffprobe -show_packets file.mov
这给了我一个输出(当然还有更多的数据包):
[PACKET]
codec_type=audio
stream_index=0
pts=221184
pts_time=5.015510
dts=221184
dts_time=5.015510
duration=580
duration_time=0.013152
convergence_duration=N/A
convergence_duration_time=N/A
size=304
pos=4833575
flags=K_
[/PACKET]
[PACKET]
codec_type=video
stream_index=1
pts=29800
pts_time=4.966667
dts=29400
dts_time=4.900000
duration=200
duration_time=0.033333
convergence_duration=N/A
convergence_duration_time=N/A
size=20707
pos=4837376
flags=__
[/PACKET]
Run Code Online (Sandbox Code Playgroud)
在上面的场景中,结尾 pts221764用于音频和30000视频 ( pts + duration)。
我想知道是否有一种简单的方法可以直接通过 ffprobe 标志或通过智能解析输出来获取最终的音频/视频数据包 pts。
在 C 或 bash 中,
我想知道如果可能的话,如何从 ssh 会话内部获取伪终端主机的文件描述符,该伪终端主机负责将输入输入到该会话的从站(pts)。
我用ffmpeg来获取视频信息.输出是
Duration: 00:05:57.00, start: 0.000000, bitrate: 611 kb/s Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 808x610, 609 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc
Run Code Online (Sandbox Code Playgroud)
时基用于某种方式(这也是我的另一个问题)计算何时解码并显示框架,对吧?那么使用它的时基,容器(12800)还是编解码器(50)?
另一个问题是为什么tbn = 12800而不是90000?
我正在尝试叠加 2 个视频,其中一个(位于“底部”的视频)我想延迟开始(假设延迟 2 秒)。
因此,要么在延迟期间保留第一帧,要么在延迟期间保留黑帧。我对哪个没有偏好。
这是我根据类似问题尝试的方法:https://superuser.com/questions/734234/delayed-video-overlay-using-ffmpeg
ffmpeg
-i video_top
-i video_bottom
-filter_complex
"[0:v]trim=start='00\:04\:17.8':end='00\:04\:32.8',setpts=PTS-STARTPTS, scale=-1:'ih-ih*.5':eval=frame[v0];
[0:a]atrim=start='00\:04\:17.8':end='00\:04\:32.8',asetpts=PTS-STARTPTS[a0];
[1:v]setpts=PTS-STARTPTS+2/TB, format=yuva420p[v1];
[v1][v0]overlay=y=(main_h-overlay_h)*.074:format=yuv444:shortest=0:alpha='straight',format=yuv420p[out]"
-map [out] -map [a0] -vcodec libx264 testing_14.mp4
Run Code Online (Sandbox Code Playgroud)
然而,这样做的结果是两个视频都在延迟的持续时间内冻结第一帧(在本例中为 2 秒)。我尝试了很多替代选择,包括
-itsoffsetPTS代替似乎什么都不起作用。