Lecture D'une vidéo de MemoryStream, en utilisant FFMpeg

j'ai du mal à chercher comment lire un fichier vidéo depuis un TMemoryStream (ou un tampon similaire en mémoire) en utilisant FFMpeg. J'ai vu beaucoup de choses, y compris UltraStarDX, des composants FFMpeg chers pour Delphi et ainsi de suite.

Un composant appelé FFMpeg Vcl Player prétend lire des formats vidéo à partir d'un flux de mémoire. J'ai téléchargé la version d'essai et je suppose qu'il utilise CircularBuffer.pas pour cette question (peut-être).

quelqu'un sait comment faire cette?

Modifier: Maintenant, la meilleure question Est de savoir comment lire un fichier vidéo crypté, en utilisant FFMpeg ou des bibliothèques similaires.

14
demandé sur Delphi.Boy 2013-11-05 13:10:36

3 réponses

pour lire la vidéo à partir du flux de mémoire, vous pouvez utiliser custom 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..
17
répondu pogorskiy 2014-06-02 06:52:24

vous pouvez perdre votre temps à réécrire FFMPEG de C++ à Delphi, ou à vous en prendre aux bibliothèques wrapper.

ou si vous êtes simplement intéressé par la lecture d'une vidéo dans Delphi, alors vérifiez les composants VideoLab de Mitov.

http://www.mitov.com/products/videolab#components

1
répondu David Schwartz 2014-06-02 23:36:50

si vous voulez jouer à partir de la mémoire, vous pouvez créer une mémoire virtuelle. Je suggère BoxedAppSdk.

cela vous aidera à faire un disque virtuel avec des fichiers virtuels que vous pouvez écrire dessus et ensuite donner le chemin virtuel vers le composant du lecteur que vous avez.

BoxedApp n'est pas libre, mais il est vraiment génial et très simple à utiliser!

1
répondu Loghman 2014-06-03 06:47:56