100行代码的简单视频播放器(ffmpeg4.1.3+SDL2.0.9)
程序员文章站
2022-07-01 13:32:13
...
100行代码的简单视频播放器
#include <stdio.h>
#include <signal.h>
#include "SDL2/SDL.h"
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
const char *stream_source = "/home/user1/test.mp4";
const unsigned int frame_width = 1920;
const unsigned int frame_height = 1080;
const unsigned int display_width = 960;
const unsigned int display_height = 540;
void force_exit() {
fprintf(stderr, "video_player stop!!!\n");
exit(0);
}
int main() {
signal(SIGINT, force_exit);
if (SDL_Init(SDL_INIT_VIDEO)) {
fprintf(stderr, "[video_player] Error: Could not initialize. %s\n", SDL_GetError());
return -1;
}
SDL_Window *screen = SDL_CreateWindow("video_player", 0, 0, display_width, display_height, SDL_WINDOW_OPENGL);
if (!screen) {
fprintf(stderr, "[video_player] Error: could not create window. %s\n", SDL_GetError());
return -1;
}
SDL_Renderer *sdl_renderer = SDL_CreateRenderer(screen, -1, 0);
SDL_Texture *sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,
frame_width, frame_height);
AVFormatContext *format_ctx = NULL;
int err_code = avformat_open_input(&format_ctx, stream_source, NULL, NULL);
if (err_code < 0) {
fprintf(stderr, "[video_player] Error: avformat_open_input failed! err_code = %d\n", err_code);
return -1;
}
err_code = avformat_find_stream_info(format_ctx, NULL);
if (err_code < 0) {
fprintf(stderr, "[video_player] Error: avformat_find_stream_info failed! err_code = %d\n", err_code);
return -1;
}
int stream_type = -1;
for (int i = 0; i < format_ctx->nb_streams; i++) {
if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
stream_type = i;
break;
}
}
if (stream_type == -1) {
fprintf(stderr, "[video_player] Error: NOT find a video stream. ERROR! \n");
return -1;
}
AVCodec *codec = avcodec_find_decoder(format_ctx->streams[stream_type]->codecpar->codec_id);
if (codec == NULL) {
fprintf(stderr, "[video_player] Error: Unsupported codec. ERROR! \n");
return -1;
}
AVCodecContext *avctx = avcodec_alloc_context3(codec);
if (avctx == NULL) {
fprintf(stderr, "[video_player] Error: Unsupported codec. ERROR! \n");
return -1;
}
err_code = avcodec_parameters_to_context(avctx, format_ctx->streams[stream_type]->codecpar);
if (err_code != 0) {
fprintf(stderr, "[video_player] Error: avcodec_parameters_to_context\n");
return -1;
}
err_code = avcodec_open2(avctx, codec, NULL);
if (err_code != 0) {
fprintf(stderr, "[video_player] Error: can not open the codec! ERROR! \n");
return -1;
}
AVFrame *frame = av_frame_alloc();
if (frame == NULL) {
fprintf(stderr, "[video_player] Error: pFrame alloc fail! ERROR!\n");
return -1;
}
AVPacket *raw_packet = av_packet_alloc();
if (raw_packet == NULL) {
fprintf(stderr, "[video_player] Error: raw_packet alloc fail!\n");
return -1;
}
while (av_read_frame(format_ctx, raw_packet) >= 0) {
if (raw_packet->stream_index != stream_type) {
continue;
}
int ret = avcodec_send_packet(avctx, raw_packet);
if (0 != ret) {
fprintf(stderr, "[video_player] Error: avcodec_send_packet failed! ret = %d\n", ret);
continue;
}
ret = avcodec_receive_frame(avctx, frame);
if (0 != ret) {
fprintf(stderr, "[video_player] Error: avcodec_receive_frame failed! ret = %d\n", ret);
continue;
}
SDL_UpdateYUVTexture(sdl_texture, NULL,
frame->data[0], frame->linesize[0],
frame->data[1], frame->linesize[1],
frame->data[2], frame->linesize[2]);
SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL);
SDL_RenderPresent(sdl_renderer);
SDL_Delay(40);
}
av_frame_free(&frame);
av_packet_free(&raw_packet);
avformat_close_input(&format_ctx);
avcodec_close(avctx);
SDL_Quit();
return 0;
}
推荐阅读
-
php 网页播放器用来播放在线视频的代码(自动判断并选择视频文件类型)
-
js制作简单的音乐播放器的示例代码
-
将Matplotlib可视化的连续帧的图像转化为视频(代码简单且直接可用)
-
FFmpeg 从零开始开发简单的音视频播放器(四)
-
Android平台下的FFmpeg的学习之路------(五)音视频同步+最简单的视频播放器
-
100行代码的简单视频播放器(ffmpeg4.1.3+SDL2.0.9)
-
JS实现简单控制视频播放倍速的实例代码
-
php 网页播放器用来播放在线视频的代码(自动判断并选择视频文件
-
php 网页播放器用来播放在线视频的代码(自动判断并选择视频文件类型)
-
php 网页播放器用来播放在线视频的代码(自动判断并选择视频文件类型)