调整网络短视频实现
parent
d1298663f3
commit
6f56bf0fe3
@ -0,0 +1,159 @@
|
|||||||
|
//
|
||||||
|
// Created by Matthew on 2025/3/11.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Streaming.h"
|
||||||
|
|
||||||
|
#include <android/api-level.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
StreamForwarder::~StreamForwarder() {
|
||||||
|
stop();
|
||||||
|
if (inputCtx) {
|
||||||
|
avformat_close_input(&inputCtx);
|
||||||
|
}
|
||||||
|
if (outputCtx) {
|
||||||
|
if (outputCtx->pb) {
|
||||||
|
avio_closep(&outputCtx->pb);
|
||||||
|
}
|
||||||
|
avformat_free_context(outputCtx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StreamForwarder::initialize(const std::string& inputUrl, const std::string& outputUrl) {
|
||||||
|
if (!openInput(inputUrl)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!openOutput(outputUrl)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StreamForwarder::openInput(const std::string& inputUrl) {
|
||||||
|
inputCtx = avformat_alloc_context();
|
||||||
|
if (!inputCtx) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avformat_open_input(&inputCtx, inputUrl.c_str(), nullptr, nullptr) < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avformat_find_stream_info(inputCtx, nullptr) < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StreamForwarder::openOutput(const std::string& outputUrl) {
|
||||||
|
int ret = avformat_alloc_output_context2(&outputCtx, nullptr, "flv", outputUrl.c_str());
|
||||||
|
if (ret < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy streams from input to output
|
||||||
|
for (unsigned int i = 0; i < inputCtx->nb_streams; i++) {
|
||||||
|
AVStream* inStream = inputCtx->streams[i];
|
||||||
|
AVStream* outStream = avformat_new_stream(outputCtx, inStream->codec->codec);
|
||||||
|
if (!outStream) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = avcodec_copy_context(outStream->codec, inStream->codec);
|
||||||
|
if (ret < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open output file
|
||||||
|
if (!(outputCtx->oformat->flags & AVFMT_NOFILE)) {
|
||||||
|
ret = avio_open(&outputCtx->pb, outputUrl.c_str(), AVIO_FLAG_WRITE);
|
||||||
|
if (ret < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write header
|
||||||
|
ret = avformat_write_header(outputCtx, nullptr);
|
||||||
|
if (ret < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamForwarder::setFrameCallback(std::function<void(uint8_t*, int, int, int)> callback) {
|
||||||
|
frameCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamForwarder::start() {
|
||||||
|
isRunning = true;
|
||||||
|
forwardPackets();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamForwarder::stop() {
|
||||||
|
isRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamForwarder::forwardPackets() {
|
||||||
|
AVPacket packet;
|
||||||
|
AVFrame* frame = av_frame_alloc();
|
||||||
|
|
||||||
|
while (isRunning) {
|
||||||
|
if (av_read_frame(inputCtx, &packet) < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process video frames if callback is set
|
||||||
|
if (frameCallback && packet.stream_index == 0) { // Assuming video is stream 0
|
||||||
|
AVCodecContext* codecCtx = inputCtx->streams[packet.stream_index]->codec;
|
||||||
|
int ret = avcodec_send_packet(codecCtx, &packet);
|
||||||
|
if (ret < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ret >= 0) {
|
||||||
|
ret = avcodec_receive_frame(codecCtx, frame);
|
||||||
|
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||||
|
break;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
processFrame(frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward packet
|
||||||
|
av_packet_rescale_ts(&packet,
|
||||||
|
inputCtx->streams[packet.stream_index]->time_base,
|
||||||
|
outputCtx->streams[packet.stream_index]->time_base);
|
||||||
|
|
||||||
|
int ret = av_interleaved_write_frame(outputCtx, &packet);
|
||||||
|
if (ret < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
av_packet_unref(&packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
av_frame_free(&frame);
|
||||||
|
av_write_trailer(outputCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamForwarder::processFrame(AVFrame* frame) {
|
||||||
|
if (frameCallback) {
|
||||||
|
frameCallback(frame->data[0], frame->linesize[0],
|
||||||
|
frame->width, frame->height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -0,0 +1,50 @@
|
|||||||
|
//
|
||||||
|
// Created by Matthew on 2025/3/11.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MICROPHOTO_STREAMING_H
|
||||||
|
#define MICROPHOTO_STREAMING_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <android/multinetwork.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <libavcodec/avcodec.h>
|
||||||
|
#include <libavformat/avformat.h>
|
||||||
|
#include <libavutil/avutil.h>
|
||||||
|
#include <libswscale/swscale.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
class Streaming
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Streaming() {}
|
||||||
|
virtual void start() {}
|
||||||
|
virtual void stop() {}
|
||||||
|
};
|
||||||
|
#if 0
|
||||||
|
class StreamForwarder : public Streaming
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
AVFormatContext* inputCtx = nullptr;
|
||||||
|
AVFormatContext* outputCtx = nullptr;
|
||||||
|
bool isRunning = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
StreamForwarder() = default;
|
||||||
|
virtual ~StreamForwarder();
|
||||||
|
|
||||||
|
bool initialize(const std::string& inputUrl, const std::string& outputUrl);
|
||||||
|
virtual void start();
|
||||||
|
virtual void stop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool openInput(const std::string& inputUrl);
|
||||||
|
bool openOutput(const std::string& outputUrl);
|
||||||
|
void forwardPackets();
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //MICROPHOTO_STREAMING_H
|
Loading…
Reference in New Issue