gpt4 book ai didi

python - 在 python 中使用内存中的 libVLC 播放视频

转载 作者:行者123 更新时间:2023-11-28 22:53:16 25 4
gpt4 key购买 nike

我试图在将文件读入内存后使用 libVLC python 绑定(bind)来播放文件。我有以下代码将有效的视频文件读入内存。我现在需要直接从内存中播放视频。

import vlc
File1 = open('vid.webm','rb')
Axel = File1.read()

现在我需要播放 Axel 中的内容,我该怎么做。

有关如何在 C、Java 等中执行此操作的信息也可以提供帮助。

编辑:我明白我将不得不使用 imem 模块,但找不到关于如何完成它的任何帮助。

最佳答案

为此,您必须使用 imem libvlc 的模块。这真的很令人困惑,因为它现在不是一个公开记录的 API。但是,我在这里和 VideoLan 论坛上关注了其他一些与此相关的帖子。下面是我今天使用 C++ 编写的一些示例代码,它使用加载到内存中的 JPEG 图像来创建视频流。您可以按照类似的步骤操作,但您只需更改内存中数据的编解码器(参见 imem-codec=RV24 行)。

// Local file/media source.
std::string IMEM_SOURCE_FOLDER = "settings/rvideo/samples/bigdog";

class MyImemData
{
public:
MyImemData() : mFrame(0), mDts(0), mPts(0) {}
~MyImemData() {}
std::vector<cv::Mat> mImages;
std::size_t mFrame;
int64_t mDts;
int64_t mPts;
};


/**
\brief Callback method triggered by VLC to get image data from
a custom memory source. This is used to tell VLC where the
data is and to allocate buffers as needed.

To set this callback, use the "--imem-get=<memory_address>"
option, with memory_address the address of this function in memory.

When using IMEM, be sure to indicate the format for your data
using "--imem-cat=2" where 2 is video. Other options for categories are
0 = Unknown,
1 = Audio,
2 = Video,
3 = Subtitle,
4 = Data

When creating your media instance, use libvlc_media_new_location and
set the location to "imem:/" and then play.

\param[in] data Pointer to user-defined data, this is your data that
you set by passing the "--imem-data=<memory_address>" option when
initializing VLC instance.
\param[in] cookie A user defined string. This works the same way as
data, but for string. You set it by adding the "--imem-cookie=<your_string>"
option when you initialize VLC. Use this when multiple VLC instances are
running.
\param[out] dts The decode timestamp, value is in microseconds. This value
is the time when the frame was decoded/generated. For example, 30 fps
video would be every 33 ms, so values would be 0, 33333, 66666, 99999, etc.
\param[out] pts The presentation timestamp, value is in microseconds. This
value tells the receiver when to present the frame. For example, 30 fps
video would be every 33 ms, so values would be 0, 33333, 66666, 99999, etc.
\param[out] flags Unused,ignore.
\param[out] bufferSize Use this to set the size of the buffer in bytes.
\param[out] buffer Change to point to your encoded frame/audio/video data.
The codec format of the frame is user defined and set using the
"--imem-codec=<four_letter>," where 4 letter is the code for your
codec of your source data.
*/
int MyImemGetCallback (void *data,
const char *cookie,
int64_t *dts,
int64_t *pts,
unsigned *flags,
size_t * bufferSize,
void ** buffer)
{
MyImemData* imem = (MyImemData*)data;

if(imem == NULL)
return 1;
// Loop...
if(imem->mFrame >= imem->mImages.size())
{
imem->mFrame = 0;
}
// Changing this value will impact the playback
// rate on the receiving end (if they use the dts and pts values).
int64_t uS = 33333; // 30 fps

cv::Mat img = imem->mImages[imem->mFrame++];
*bufferSize = img.rows*img.cols*img.channels();
*buffer = img.data;
*dts = *pts = imem->mDts = imem->mPts = imem->mPts + uS;

return 0;
}


/**
\brief Callback method triggered by VLC to release memory allocated
during the GET callback.

To set this callback, use the "--imem-release=<memory_address>"
option, with memory_address the address of this function in memory.

\param[in] data Pointer to user-defined data, this is your data that
you set by passing the "--imem-data=<memory_address>" option when
initializing VLC instance.
\param[in] cookie A user defined string. This works the same way as
data, but for string. You set it by adding the "--imem-cookie=<your_string>"
option when you initialize VLC. Use this when multiple VLC instances are
running.
\param[int] bufferSize The size of the buffer in bytes.
\param[out] buffer Pointer to data you allocated or set during the GET
callback to handle or delete as needed.
*/
int MyImemReleaseCallback (void *data,
const char *cookie,
size_t bufferSize,
void * buffer)
{
// Since I did not allocate any new memory, I don't need
// to delete it here. However, if you did in your get method, you
// should delete/free it here.
return 0;
}


/**
\brief Method to load a series of images to use as raw image data
for the network stream.

\param[in] sourceFolder Path to folder containing jpeg or png images.
*/
std::vector<cv::Mat> GetRawImageData(const std::string& sourceFolder)
{
namespace fs = boost::filesystem;
std::vector<cv::Mat> result;
std::vector<std::string> filenames;
if( fs::exists(sourceFolder) && fs::is_directory(sourceFolder) )
{
for(fs::directory_iterator dir(sourceFolder);
dir != fs::directory_iterator();
dir++)
{
std::string ext = dir->path().extension().string();
if( fs::is_regular_file( dir->status() ) &&
(dir->path().extension() == ".jpeg" ||
dir->path().extension() == ".png") )
{
filenames.push_back(dir->path().string());
}
}
}

if(filenames.size() > 0)
{
// Sort from 0 to N
std::sort(filenames.begin(), filenames.end());
std::vector<std::string>::iterator filename;
for(filename = filenames.begin();
filename != filenames.end();
filename++)
{
cv::Mat img = cv::imread(*filename);
result.push_back(img);
}
}
return result;
}


int main(int argc, char* argv[])
{

// Load images first since we need to know
// the size of the image data for IMEM
MyImemData data;
data.mImages =
GetRawImageData(IMEM_SOURCE_FOLDER);

if(data.mImages.size() == 0)
{
std::cout << "No images found to render/stream.";
return 0;
}

int w, h, channels;
w = data.mImages.front().cols;
h = data.mImages.front().rows;
channels = data.mImages.front().channels();

// You must create an instance of the VLC Library
libvlc_instance_t * vlc;
// You need a player to play media
libvlc_media_player_t *mediaPlayer;
// Media object to play.
libvlc_media_t *media;

// Configure options for this instance of VLC (global settings).
// See VLC command line documentation for options.
std::vector<const char*> options;
std::vector<const char*>::iterator option;
options.push_back("--no-video-title-show");

char imemDataArg[256];
sprintf(imemDataArg, "--imem-data=%#p", &data);
options.push_back(imemDataArg);

char imemGetArg[256];
sprintf(imemGetArg, "--imem-get=%#p", MyImemGetCallback);
options.push_back(imemGetArg);

char imemReleaseArg[256];
sprintf(imemReleaseArg, "--imem-release=%#p", MyImemReleaseCallback);
options.push_back(imemReleaseArg);

options.push_back("--imem-cookie=\"IMEM\"");
// Codec of data in memory for IMEM, raw 3 channel RGB images is RV24
options.push_back("--imem-codec=RV24");
// Video data.
options.push_back("--imem-cat=2");

// If using RAW image data, like RGB24, then you
// must specify the width, height, and number of channels
// to IMEM. Other codes may have that information within
// the data buffer, but RAW will not.
char imemWidthArg[256];
sprintf(imemWidthArg, "--imem-width=%d", w);
options.push_back(imemWidthArg);

char imemHeightArg[256];
sprintf(imemHeightArg, "--imem-height=%d", h);
options.push_back(imemHeightArg);

char imemChannelsArg[256];
sprintf(imemChannelsArg, "--imem-channels=%d", channels);
options.push_back(imemChannelsArg);

//options.push_back("--verbose=2");

// Load the VLC engine
vlc = libvlc_new (int(options.size()), options.data());

// Create a media item from file
media = libvlc_media_new_location (vlc, "imem://");

// Configure any transcoding or streaming
// options for the media source.
options.clear();

// Stream as MPEG2 via RTSP
//options.push_back(":sout=#transcode{venc=ffmpeg{keyint=1,min-keyint=1,tune=zerolatency,bframes=0,vbv-bufsize=1200}, vcodec=mp2v,vb=800}:rtp{sdp=rtsp://:1234/BigDog}");

// Stream as MJPEG (Motion JPEG) to http destination. MJPEG encoder
// does not currently support RTSP
//options.push_back(":sout=#transcode{vcodec=MJPG,vb=800,scale=1,acodec=none}:duplicate{dst=std{access=http,mux=mpjpeg,noaudio,dst=:1234/BigDog.mjpg}");

// Convert to H264 and stream via RTSP
options.push_back(":sout=#transcode{vcodec=h264,venc=x264,vb=0,vbv-bufsize=1200,bframes=0,scale=0,acodec=none}:rtp{sdp=rtsp://:1234/BigDog}");

// Set media options
for(option = options.begin(); option != options.end(); option++)
{
libvlc_media_add_option(media, *option);
}

// Create a media player playing environment
mediaPlayer = libvlc_media_player_new_from_media (media);

// No need to keep the media now
libvlc_media_release (media);

// play the media_player
libvlc_media_player_play (mediaPlayer);

boost::this_thread::sleep(boost::posix_time::milliseconds(60000));

// Stop playing
libvlc_media_player_stop (mediaPlayer);

// Free the media_player
libvlc_media_player_release (mediaPlayer);
// Free vlc
libvlc_release (vlc);

return 0;
}

关于python - 在 python 中使用内存中的 libVLC 播放视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19602790/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com