delphi - 使用 FFMpeg 播放 MemoryStream 中的视频

标签 delphi ffmpeg

我很难搜索如何使用 FFMpeg 从 TMemoryStream(或内存中的类似缓冲区)播放视频文件。我见过很多东西,包括UltraStarDX、用于Delphi的昂贵的FFMpeg组件等等。

一个名为 FFMpeg Vcl Player 的组件声称可以播放内存流中的视频格式。我下载了试用版,我猜它使用了 CircularBuffer.pas(也许)。

有人知道如何做到这一点吗?

编辑: 现在更好的问题是如何使用 FFMpeg 或类似的库播放加密的视频文件。

最佳答案

要播放内存流中的视频,您可以使用自定义AVIOContext

static const int kBufferSize = 4 * 1024;

class my_iocontext_private
{
private:
    my_iocontext_private(my_iocontext_private const &);
    my_iocontext_private& operator = (my_iocontext_private const &);

public:
    my_iocontext_private(IInputStreamPtr inputStream)
       : inputStream_(inputStream)
       , buffer_size_(kBufferSize)
       , buffer_(static_cast<unsigned char*>(::av_malloc(buffer_size_))) {
    ctx_ = ::avio_alloc_context(buffer_, buffer_size_, 0, this,
           &my_iocontext_private::read, NULL, &my_iocontext_private::seek); 
    }

    ~my_iocontext_private() { 
        ::av_free(ctx_);
        ::av_free(buffer_); 
    }

    void reset_inner_context() { ctx_ = NULL; buffer_ = NULL; }

    static int read(void *opaque, unsigned char *buf, int buf_size) {
        my_iocontext_private* h = static_cast<my_iocontext_private*>(opaque);
        return h->inputStream_->Read(buf, buf_size); 
    }

    static int64_t seek(void *opaque, int64_t offset, int whence) {
        my_iocontext_private* h = static_cast<my_iocontext_private*>(opaque);

        if (0x10000 == whence)
            return h->inputStream_->Size();

        return h->inputStream_->Seek(offset, whence); 
    }

    ::AVIOContext *get_avio() { return ctx_; }

    private:
       IInputStreamPtr inputStream_; // abstract stream interface, You can adapt it to TMemoryStream  
       int buffer_size_;
       unsigned char * buffer_;  
       ::AVIOContext * ctx_;
   };


   //// ..........

   /// prepare input stream:
   IInputStreamPtr inputStream = MyCustomCreateInputStreamFromMemory();

   my_iocontext_private priv_ctx(inputStream);
   AVFormatContext * ctx = ::avformat_alloc_context();
   ctx->pb = priv_ctx.get_avio();

   int err = avformat_open_input(&ctx, "arbitrarytext", NULL, NULL);
   if (err < 0) 
       return -1;

   //// normal usage of ctx
   //// avformat_find_stream_info(ctx, NULL);
   //// av_read_frame(ctx, &pkt); 
   //// etc..

关于delphi - 使用 FFMpeg 播放 MemoryStream 中的视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19785254/

相关文章:

Delphi 等待文件复制过程完成

delphi - 如何在 ListView 中显示文本文件中的数据?

ffmpeg - 如何从 .srt 字幕和 .ts 视频转到带有 dvb_subtitles 的 .ts 视频?

javascript - HLS 转 MPEG DASH

ffmpeg - 如何将两个 ffmpeg 查询合并到一个管道?

opengl - 无法正确初始化 AVFrame 以进行 sws_scale 转换

delphi - 获取 Delphi 中 OpenSSL DLL 的版本和/或位置?

delphi - delphi中如何删除omnixml中的特定节点

delphi - 修改exe资源中的字符串

node.js - AWS lambda 错误 : Cant find ffmpeg