我通过v4l从相机抓取视频帧,我需要用mpeg4格式对它们进行转码,然后通过RTP连续流式传输.
一切都"有效",但重新编码时我没有:输入流产生15fps,输出为25fps,每个输入帧都在一个视频对象序列中转换(我通过简单的检查验证了这一点)在输出比特流上).我猜接收器正在正确解析mpeg4比特流,但RTP分组化在某种程度上是错误的.我应该如何在一个或多个AVPacket中拆分编码比特流?也许我错过了明显的,我只需要寻找B/P帧标记,但我想我没有正确使用编码API.
以下是我的代码的摘录,它基于可用的ffmpeg示例:
// input frame
AVFrame *picture;
// input frame color-space converted
AVFrame *planar;
// input format context, video4linux2
AVFormatContext *iFmtCtx;
// output codec context, mpeg4
AVCodecContext *oCtx;
// [ init everything ]
// ...
oCtx->time_base.num = 1;
oCtx->time_base.den = 25;
oCtx->gop_size = 10;
oCtx->max_b_frames = 1;
oCtx->bit_rate = 384000;
oCtx->pix_fmt = PIX_FMT_YUV420P;
for(;;)
{
// read frame
rdRes = av_read_frame( iFmtCtx, &pkt );
if ( rdRes >= 0 && pkt.size > 0 )
{
// decode it
iCdcCtx->reordered_opaque …Run Code Online (Sandbox Code Playgroud) 我正在开发一个视频流媒体网站,用户可以将视频上传到网站(使用uploadify jquery插件一次播放多个视频).
现在,我面临的问题是将视频编码为FLV以便在线流式传输.
应该何时进行视频编码过程?它应该在上传完成后立即发生(即重定向用户上传成功页面,然后使用exec命令在后台开始编码ffmpeg?)但是,使用这种方法,我如何确定编码是否成功完成?如果用户上传损坏的视频并且ffmpeg无法编码,该怎么办?我如何在PHP中处理这个?
如何排队视频编码,因为多个用户可以同时上传视频?FFMpeg有自己的编码队列吗?
我还在另一个相关的SO线程中阅读了有关gearman和消息队列选项的信息,例如redis和AMQP.这些是潜在的解决方案吗?
如果有人能回答我的问题,我将非常感激.
我一直试图理解视频编码如何适用于现代编码器,特别是H264.在文档中经常提到残差帧是根据当前p帧和最后一个i帧之间的差异创建的(假设在预测中未使用以下帧).我知道使用YUV颜色空间(可能是YV12),并且一个图像从另一个图像"减去"然后形成残差.我不明白的是这种减法究竟是如何运作的.我不认为这是差异的绝对值,因为这将是模棱两可的.获得这种差异的每像素公式是什么?
我开始使用ffmpeg,我想将avi文件转换为mp4/h264文件.我已经阅读了很多帖子,包括这个,但我找不到任何好的例子如何将帧保存到mp4文件.下面的代码是简化的代码,它解码来自avi文件的帧并将其编码为H264/mp4文件,但是当我保存帧时,mp4文件无法播放.我想我在编码方面做了一些错误
如果你能告诉我什么是错的以及如何解决它,我将不胜感激.
const char* aviFileName = "aviFrom.avi";
const char* mp4FileName = "mp4To.mp4";
// Filling pFormatCtx by open video file and Retrieve stream information
// ...
// Retrieving codecCtxDecode and opening codecDecode
//...
// Get encoder
codecCtxEncode = avcodec_alloc_context();
codecCtxEncode->qmax = 69;
codecCtxEncode->max_qdiff = 4;
codecCtxEncode->bit_rate = 400000;
codecCtxEncode->width = codecCtxDecode->width;
codecCtxEncode->height = codecCtxDecode->height;
codecCtxEncode->pix_fmt = AV_PIX_FMT_YUV420P;
codecEncode = avcodec_find_encoder(CODEC_ID_H264);
if(codecEncode == NULL)
return -1;
if(avcodec_open2(codecCtxEncode, codecEncode, NULL))
return -1;
SwsContext *sws_ctx = sws_getContext(codecCtxDecode->width, codecCtxDecode->height, codecCtxDecode->pix_fmt,
codecCtxDecode->width, codecCtxDecode->height, AV_PIX_FMT_YUV420P, …Run Code Online (Sandbox Code Playgroud) 我希望通过ffmpeg中的选择场景,根据检测到每个镜头的第一帧,将一个视频分成多个部分.
以下条目记录场景帧并从中创建照片拼接.这向我表明选择部分是功能性的,但我想用它来创建许多单独的视频,每个视频都是自己的视频文件.
ffmpeg -i video.mpg -vf select='gt(scene\,0.2331)','scale=320x240,tile=1x100' -frames:v preview.png
Run Code Online (Sandbox Code Playgroud)
谢谢.我想我很接近,我愿意接受任何解决方案.
按照ffmpeg:decoding_encoding.c和filtering_video.c的exmaples,我处理iPhone拍摄的一个视频文件.视频文件:.mov,视频尺寸; 480x272,视频编解码器:H.264/AVC,每秒30帧,比特率:605 kbps.
我首先提取每个帧,即YUV.我将YUV转换为RGB24,并处理RGB24,然后将RGB24写入.ppm文件.它显示.ppm文件是正确的.
然后我计划将处理过的RGB24帧编码为视频文件.由于MPEG不支持RGB24图像格式,我使用了AV_CODEC_ID_HUFFYUV.但输出视频文件(显示18.5 MB)无法播放.Ubuntu上的电影播放器声称有错误:无法确定流的类型.我也在VCL上尝试过.它根本不起作用,没有任何错误信息.
我的第二个问题是:对于输入视频文件中的每个提取的帧,我根据filtering_video.c得到如下:
frame->pts = av_frame_get_best_effort_timestamp(frame);
我打印出每个帧的pts,发现它增加了20,如下所示:
pFrameRGB_count: 0, frame->pts: 0
pFrameRGB_count: 1, frame->pts: 20
pFrameRGB_count: 2, frame->pts: 40
pFrameRGB_count: 3, frame->pts: 60
Run Code Online (Sandbox Code Playgroud)
其中frame是输入视频中提取的帧,pFrameRGB_count是RGB24格式的已处理帧的计数.
他们为什么错了?
我正在尝试录制一段10秒钟的视频进行监控.在Android中使用MediaRecorder非常简单.我所要做的就是打电话
mediaRecorder.setMaxDuration(10000);
Run Code Online (Sandbox Code Playgroud)
但是,我想连续覆盖相同的10秒视频.同样,这是一项微不足道的任务.
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
switch (what) {
case MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED:
stopRecording();
startRecording();
break;
}
}
Run Code Online (Sandbox Code Playgroud)
停止和启动(重新设定)MediaRecorder大约需要两秒钟.如果在这两秒钟内发生了重要事情,我就不会记录下来.
因此,我通过使用LocalSocket跟踪其他几个具有相同问题的人,并将其描述符传递给MediaRecorder
mediaRecorder.setOutputFile(sender.getFileDescriptor());
Run Code Online (Sandbox Code Playgroud)
然后是一个包含LocalServerSocket和接收器LocalSocket的AyncTask
public class VirtualServer extends AsyncTask<Void, Void, Void> {
...
server = new LocalServerSocket(SOCKET_ADDRESS);
while (true) {
receiver = server.accept();
...
int len = 0;
byte[] data = new byte[1024];
while ((len = input.read(data)) >= 0) {
...
Run Code Online (Sandbox Code Playgroud)
看看这是怎么回事?一旦解决了,就会出现一个新问题,在StackOverflow上也会多次解决.问题是传递给MediaRecorder的文件描述符不可搜索.
对我而言,这是我的理解停止的地方.不幸的是,没有明确的问题描述.如果有人可以向我描述问题,我可以开始寻找解决方案.有些地方提到"moot"必须重新定位,但随后讨论会转向一般的mp4编码,我迷失在所有细节中.
我希望我的问题得到明确说明.我不想播放任何形式的视频.深入研究打包成RTP并尝试提取我真正需要的部分的代码让我更加困惑.
我已经看过的链接:
干杯.
android video-encoding mpeg-4 mediarecorder android-mediarecorder
目前,我有一个工作原型应用程序,将一个手机的相机输出流式传输到另一个手机的屏幕.
但是,流和实际视频之间的延迟范围从1秒到最多5秒.对于我的特定用例,我需要延迟不到1秒.
我发现比特率/分辨率不会影响延迟.
我正在使用libstreaming库通过wifi-direct传输h264视频.
它似乎只支持h263或h264的编码...我发现h263不像h264那样一致.
以下是捕获视频和流到RTSP服务器的代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_server);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mSurfaceView = (SurfaceView) findViewById(R.id.surface);
// Sets the port of the RTSP server to 8988
Editor editor = PreferenceManager.getDefaultSharedPreferences(
getApplicationContext()).edit();
editor.putString(RtspServer.KEY_PORT, String.valueOf(8988));
editor.commit();
// Get bitrate
int bitrate = Integer.valueOf(getIntent().getStringExtra(BITRATE));
if (bitrate < 100000)
bitrate = 100000;
// Get resolution
String resolution = getIntent().getStringExtra(RESOLUTION);
int resX = 176;
int resY = 144;
if (resolution.equals("352x288")) {
resX = 352;
resY = 288;
} else if …Run Code Online (Sandbox Code Playgroud) 是否有一些免费的代码转换器可以在飞行中将视频打包成hls或mpeg-dash?
我不想使用直播,但我想创建vod流媒体.
transcoding video-encoding video-streaming http-live-streaming mpeg-dash
好的,所以努力让我了解jcodec。基本上,我想将屏幕上的内容记录为BufferedImages,将缓冲的图像编码为H264帧,然后对其进行解码,然后将它们转换回缓冲的图像。
这是我拥有的代码,ScreenRecorder类扩展了线程并基本上在while true循环中捕获了屏幕。那部分起作用。然后,似乎也可以将ScreenRecorder中的BufferedImage编码为H264帧,但是当我尝试对其进行解码时,我得到了AIOBE
ScreenRecorder sc = new ScreenRecorder();
sc.start();
H264Encoder enc = H264Encoder.createH264Encoder();
ColorSpace cs = enc.getSupportedColorSpaces()[0];
System.out.println("cs= " + cs);
H264Decoder dec = new H264Decoder();
byte[][] buff = new byte[4096][4096];
while (true) {
BufferedImage bi = sc.getSnapshot();
System.out.println("Got bi " + bi);
if (bi != null) {
Picture pi = AWTUtil.fromBufferedImage(bi, cs);
int bufSize = enc.estimateBufferSize(pi);
ByteBuffer bb = ByteBuffer.allocate(bufSize);
VideoEncoder.EncodedFrame ef = enc.encodeFrame(pi, bb);
System.out.println("Data = " + Arrays.toString(ef.getData().array()));
Frame f = dec.decodeFrame(ef.getData(), buff);
System.out.println("Decoded frame = " …Run Code Online (Sandbox Code Playgroud) video-encoding ×10
ffmpeg ×5
h.264 ×3
android ×2
compression ×2
libavcodec ×2
video ×2
c ×1
c++ ×1
java ×1
jcodec ×1
mpeg-4 ×1
mpeg-dash ×1
php ×1
rtsp ×1
streaming ×1
transcoding ×1