回复 5楼 东海ECS

程序代码:
#include <iostream>
#include <string>
#include <thread>
#include "SDL2/SDL.h"
#include "SDL2/SDL_thread.h"
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
#include "libavutil/time.h"
#include "libswscale/swscale.h"
#include "libavutil/imgutils.h"
}
const int kVideoWidth = 640;
const int kVideoHeight = 360;
const std::string kVideoPath = "test.mp4";
const std::string kOutputPath = "output.mp4";
const int kStartTime = 5; // 单位:秒
const int kEndTime = 10; // 单位:秒
int main(int argc, char* argv[])
{
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0)
{
std::cerr << "Failed to initialize SDL: " << SDL_GetError() << std::endl;
return -1;
}
AVFormatContext* format_context = avformat_alloc_context();
if (avformat_open_input(&format_context, kVideoPath.c_str(), nullptr, nullptr) != 0)
{
std::cerr << "Failed to open video file: " << kVideoPath << std::endl;
return -1;
}
if (avformat_find_stream_info(format_context, nullptr) < 0)
{
std::cerr << "Failed to find video stream information" << std::endl;
return -1;
}
const AVCodec* codec = nullptr;
int stream_index = -1;
for (int i = 0; i < format_context->nb_streams; i++)
{
if (format_context->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
codec = avcodec_find_decoder(format_context->streams[i]->codecpar->codec_id);
stream_index = i;
break;
}
}
if (codec == nullptr)
{
std::cerr << "Failed to find video codec" << std::endl;
return -1;
}
AVCodecContext* codec_context = avcodec_alloc_context3(codec);
if (avcodec_parameters_to_context(codec_context, format_context->streams[stream_index]->codecpar) < 0)
{
std::cerr << "Failed to copy video codec parameters to context" << std::endl;
return -1;
}
if (avcodec_open2(codec_context, codec, nullptr) < 0)
{
std::cerr << "Failed to open video codec" << std::endl;
return -1;
}
AVFrame* frame = av_frame_alloc();
AVFrame* frame_rgb = av_frame_alloc();
uint8_t* buffer = nullptr;
int buffer_size = 0;
buffer_size = av_image_get_buffer_size(AV_PIX_FMT_RGB24, kVideoWidth, kVideoHeight, 1);
buffer = reinterpret_cast<uint8_t*>(av_malloc(buffer_size));
av_image_fill_arrays(frame_rgb->data, frame_rgb->linesize, buffer, AV_PIX_FMT_RGB24, kVideoWidth, kVideoHeight, 1);
struct SwsContext* sws_context = sws_getContext(codec_context->width, codec_context->height, codec_context->pix_fmt, kVideoWidth, kVideoHeight, AV_PIX_FMT_RGB24, SWS_BILINEAR, nullptr, nullptr, nullptr);
SDL_Window* window = SDL_CreateWindow("Video Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, kVideoWidth, kVideoHeight, SDL_WINDOW_OPENGL);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STREAMING, kVideoWidth, kVideoHeight);
AVPacket packet;
AVFormatContext* output_format_context = nullptr;
if (avformat_alloc_output_context2(&output_format_context, nullptr, nullptr, kOutputPath.c_str()) < 0)
{
std::cerr << "Failed to allocate output format context" << std::endl;
return -1;
}
AVStream* output_stream = avformat_new_stream(output_format_context, codec);
if (output_stream == nullptr)
{
std::cerr << "Failed to allocate output stream" << std::endl;
return -1;
}
if (avcodec_parameters_copy(output_stream->codecpar, format_context->streams[stream_index]->codecpar) < 0)
{
std::cerr << "Failed to copy codec parameters to output stream" << std::endl;
return -1;
}
output_stream->time_base = format_context->streams[stream_index]->time_base;
if (!(output_format_context->oformat->flags & AVFMT_NOFILE))
{
if (avio_open(&output_format_context->pb, kOutputPath.c_str(), AVIO_FLAG_WRITE) < 0)
{
std::cerr << "Failed to open output file" << std::endl;
return -1;
}
}
if (avformat_write_header(output_format_context, nullptr) < 0)
{
std::cerr << "Failed to write output file header" << std::endl;
return -1;
}
bool is_running = true;
int64_t start_pts = kStartTime * AV_TIME_BASE;
int64_t end_pts = kEndTime * AV_TIME_BASE;
while (av_read_frame(format_context, &packet) >= 0 && is_running)
{
if (packet.stream_index == stream_index)
{
if (avcodec_send_packet(codec_context, &packet) == 0)
{
while (avcodec_receive_frame(codec_context, frame) == 0)
{
if (frame->pts >= start_pts && frame->pts <= end_pts)
{
sws_scale(sws_context, frame->data, frame->linesize, 0, codec_context->height, frame_rgb->data, frame_rgb->linesize);
SDL_UpdateTexture(texture, nullptr, frame_rgb->data[0], frame_rgb->linesize[0]);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, nullptr, nullptr);
SDL_RenderPresent(renderer);
if (av_write_frame(output_format_context, &packet) < 0)
{
std::cerr << "Failed to write frame to output file" << std::endl;
return -1;
}
if (av_gettime_relative() >= end_pts)
{
is_running = false;
break;
}
}
}
}
}
av_packet_unref(&packet);
}
av_write_trailer(output_format_context);
av_frame_free(&frame);
av_frame_free(&frame_rgb);
avcodec_close(codec_context);
avformat_close_input(&format_context);
avformat_free_context(format_context);
av_free(buffer);
avio_close(output_format_context->pb);
avformat_free_context(output_format_context);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
图片附件: 游客没有浏览图片的权限,请
登录 或
注册
图片附件: 游客没有浏览图片的权限,请
登录 或
注册
图片附件: 游客没有浏览图片的权限,请
登录 或
注册
剪辑10秒钟视频 大小才1K。。。。
播放器 没有音频
2分4.86秒的视频。 50秒就播放完成了。。。。
你是不是要告诉我,代码如果拿到手,就可以正常使用,我就什么知识点也学不到了。。。。
写出了程序流程,让我自己找错误,这样才能更好地学习。。。。