我最初尝试过如何在Andoid exoplayer中播放原始NAL单元?但是我注意到我必须做一些低级别的事情.
我发现了这个简单的MediaCodec示例.正如您所看到的,它是一个在传递给它的表面上播放文件的线程.
注意这些线条
mExtractor = new MediaExtractor();
mExtractor.setDataSource(filePath);
Run Code Online (Sandbox Code Playgroud)
看起来我应该创建自己的MediaExtractor,而不是从文件中提取视频单元,它将使用我将提供的缓冲区中的h264 NAL单元.
然后我可以打电话mExtractor.setDataSource(MediaDataSource dataSource),看看MediaDataSource
它有 readAt(long position, byte[] buffer, int offset, int size)
这是它读取NAL单位的地方.但是,我应该如何通过它们?我没有关于需要读取的缓冲区结构的信息.
我应该通过byte[] buffer其中的NAL单位,如果是,以哪种格式?偏移量是多少?如果它是一个缓冲区,我不应该只删除读取的行,因此没有偏移或大小?
顺便说一下,h264 NAL单元是流媒体单元,它们来自RTP数据包,而不是文件.我将通过C++获取它们并将它们存储在缓冲区中,尝试传递给mediaExtractor.
更新:
我一直在阅读很多关于MediaCodec的内容,我想我更了解它.根据https://developer.android.com/reference/android/media/MediaCodec,一切都依赖于这种类型的东西:
MediaCodec codec = MediaCodec.createByCodecName(name);
MediaFormat mOutputFormat; // member variable
codec.setCallback(new MediaCodec.Callback() {
@Override
void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
// fill inputBuffer with valid data
…
codec.queueInputBuffer(inputBufferId, …);
}
@Override
void onOutputBufferAvailable(MediaCodec mc, int …Run Code Online (Sandbox Code Playgroud) 这是我在问题的确切时刻的源代码树:
https://github.com/lucaszanella/jscam/tree/cf29b3cc90df7c5c7bb2d27c2205264d52b0715d/src/jscam
我相信npm install,npm start和npm run android将使它发射(注意,ONVIF不是从NPM安装,但在NPM克隆post-install脚本,然后安装,但它被安装在node_modules同一个符号链接到其克隆的地方.我甚至试图把一切都node_modules只是在案例,但错误仍然存在).另外不要介意我在文件夹中的额外docker
无论如何,问题是:
我正在尝试在React Native中使用nodejs模块onvif,所以我使用这种技术使用babel翻译require方法并安装browserfy模块来实现核心nodejs模块.我已经测试过像crypto这样的简单例子.但是,当我尝试简单地导入onvif模块时,我得到了这个:
这是device.js第30行,看起来Cam在这里是未定义的
当我导入onvif.js哪些导入时cam.js,没有任何反应.但是当它再次device.js导入时它似乎未定义的导入cam.js
我也试过这种方法似乎避免了所有的babel翻译,但令人惊讶的是问题仍然存在.
更新:
这是新的源代码树:https://github.com/lucaszanella/jscam/tree/98b714219ed25b9d91ea3af275177f66fdb74fa2/src/jscam
我现在正在使用extraNodeModules,这是官方的方法.您可以在此处查看我的依赖项:https://github.com/lucaszanella/jscam/blob/98b714219ed25b9d91ea3af275177f66fdb74fa2/src/jscam/rn-cli.config.js
它就在这条线上:https://github.com/isaacs/sax-js/blob/d65e3bb5049893aaab4aba05198b9cd335b5a1ad/lib/sax.js#L222
它看起来仍然是相同类型的错误
更新:如果找不到dgram,请尝试
npm install lucaszanella/react-native-dgram-shim
Run Code Online (Sandbox Code Playgroud)
它已经在package.json中,它应该安装但有人抱怨它没有
我只能找到旧的C++源代码示例.无论如何,我做了我的,基于他们.这是我在python中的发布者:
import zmq
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:5563")
while True:
msg = "hello"
socket.send_string(msg)
print("sent "+ msg)
sleep(5)
Run Code Online (Sandbox Code Playgroud)
这是C++中的订阅者:
void * ctx = zmq_ctx_new();
void * subscriber = zmq_socket(ctx, ZMQ_SUB);
// zmq_connect(subscriber, "tcp://*:5563");
zmq_connect(subscriber, "tcp://localhost:5563");
// zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", sizeof(""));
while (true) {
zmq_msg_t msg;
int rc;
rc = zmq_msg_init( & msg);
assert(rc == 0);
std::cout << "waiting for message..." << std::endl;
rc = zmq_msg_recv( & msg, subscriber, 0);
assert(rc == 1);
std::cout << "received: " << (char …Run Code Online (Sandbox Code Playgroud) 我正在为Linux使用Flutter Desktop。我正在调用一个方法MarkTextureFrameAvailable,该方法应该标记要由引擎重新渲染的纹理。由于我正在为视频播放器编程,因此需要MarkTextureFrameAvailable从播放器的线程中进行调用。问题是引擎迫使我MarkTextureFrameAvailable从创建引擎的线程中调用(以及任何其他引擎方法)。
您可以看到所有对引擎的调用最终都在外壳程序中,该外壳程序始终进行检查以查看这些调用是否由创建该调用的同一线程进行:
task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()
Run Code Online (Sandbox Code Playgroud)
(https://github.com/flutter/engine/blob/master/shell/common/shell.cc#L838)
这就是我创建颤振引擎的方式:
int main(int argc, char **argv) {
//..
flutter::FlutterWindowController flutter_controller(icu_data_path);
// Start the engine.
if (!flutter_controller.CreateWindow(800, 600, "Flutter WebRTC Demo", assets_path,
arguments)) {
return EXIT_FAILURE;
}
// Register any native plugins.
FlutterWebRTCPluginRegisterWithRegistrar(
flutter_controller.GetRegistrarForPlugin("FlutterWebRTCPlugin"));
// Run until the window is closed.
flutter_controller.RunEventLoop();
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,创建引擎的线程被阻塞了,flutter_controller.RunEventLoop();这是我可以放置事件分配器的唯一地方,该事件分配器迫使事情从main的线程执行。我不喜欢这个主意。即使RunEventLoopWithTimeout存在,我也需要超时并继续检查队列中是否有MarkTextureFrameAvailable呼叫。我认为这不是最佳选择。
那么我应该如何MarkTextureFrameAvailable从主线程调用?
我在MarkTextureFrameAvailable这里找到了一个用法示例:https : //github.com/cloudwebrtc/flutter-webrtc/blob/desktop/common/src/flutter_video_renderer.cc#L90,它看起来像是另一个调用它的线程。这怎么可能?当我这样做时,我得到一个致命错误,但他确实发生了并且行得通吗?
我花了两天的时间来弄清楚在此示例中哪个线程调用了OnFrame,但由于使用https://github.com/flutter-webrtc/libwebrtc而使用了Google的webrtc ,因此找不到它:https …
Mozilla 的本教程解释了如何为 Rust 生成独立的工具链
mkdir NDK
${NDK_HOME}/build/tools/make_standalone_toolchain.py --api 26 --arch arm64 --install-dir NDK/arm64
${NDK_HOME}/build/tools/make_standalone_toolchain.py --api 26 --arch arm --install-dir NDK/arm
${NDK_HOME}/build/tools/make_standalone_toolchain.py --api 26 --arch x86 --install-dir NDK/x86
Run Code Online (Sandbox Code Playgroud)
ar如果我理解正确的话,这些主要是需要的linker。clang++ 当然不会用。
但本教程很旧,根据https://developer.android.com/ndk/guides/standalone_toolchain,该脚本已过时。它说As of r19, the NDK's default toolchains are standalone toolchains, which renders this process unnecessary.
我认为我应该将我的cargo-config.toml位置指向此。
然而,这是 2021 年 Android 的正确编译方式吗?
我知道exoplayer对RTSP的支持,但我需要C++是从大量的操作系统的播放器代码工作,所以我需要传递给exoplayer之前,在解析C++到NAL单元的RTP包
我找到了一种使用live555解码RTP数据包并提取其NAL单元的方法.根据ExoPlayer的文档:
所有ExoPlayer实现的通用组件是:
MediaSource,用于定义要播放的媒体,加载媒体,以及从中读取加载的媒体.
在播放开始时通过ExoPlayer.prepare注入MediaSource....
所以我需要一个MediaSource可以从我的C++代码中提取NAL单元的自定义.
在MediaSource的类引用中,我们可以看到已经有一些MediaSource可用.我虽然也许SmoothStreaming MediaSource可以工作但是没有描述它究竟做什么,并且在它的构造函数中我必须提供一个Uri或一个SsManifest(什么).
我可以看到这个库中存在一个NAL单元实用程序,所以可能已经完成了一半
那么如何构建或使用已有的MediaSource读取NAL单元以供ExoPlayer播放?
作为附加组件,您如何将NAL单元从C++传递到Java?在代码中我发现它只是将它们存储在C++缓冲区中.我应该以某种方式用Java读取这个缓冲区吗?
更新:
我一直在研究这个图书馆是如何运作的.这一切都始于一个MediaSource,它有像Extractor和DataSource这样的对象.似乎ExtractorMediaSource是MediaSource您可以提供自己的Extractor和DataSource.
据我所知,DataSource是一个从任何可能的地方获取原始字节的类,无论是文件读取还是网络数据包.基于Extractor库上的可用类,Mp4Extractor和Mp3Extractor,Extractor可以解释从中读取的数据DataSource.Extractor界面的两个主要方法是:
void init(ExtractorOutput output)
int read(ExtractorInput input, PositionHolder seekPosition)
Run Code Online (Sandbox Code Playgroud)
我不知道什么是ExtractorInput与ExtractorInput对,但它们看起来很重要.
所以以某种方式Extractor读取DataSource,解析它并以通用格式发送给 …
我正在尝试EGLImageKHR将从NVIDIA解码器获得的图像渲染到帧缓冲区,以便可以在屏幕上渲染此帧缓冲区。我编写了执行以下操作的代码:
创建两个纹理,frameBufferTexture和externalTexture。我们写EGLImage到externalTexture和借鉴,以frameBufferTexture从externalTexture。然后,我们读出frameBufferTexture用glReadPixels:
glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glGenTextures(1, &externalTexture);
glGenTextures(1, &frameBufferTexture);
glBindTexture(GL_TEXTURE_2D, frameBufferTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, decodedNvFrame->width, decodedNvFrame->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glUniform1i(texLocation, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glBindTexture(GL_TEXTURE_2D, frameBufferTexture);
EGLImageKHR hEglImage;
hEglImage = NvEGLImageFromFd(eglDisplay, decodedNvFrame->nvBuffer->planes[0].fd);
if (!hEglImage)
printf("Could not get EglImage from fd. Not rendering\n");
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, frameBufferTexture, 0);
glBindTexture(GL_TEXTURE_2D, externalTexture);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, hEglImage);
glUniform1i(texLocation, 0);
glBindVertexArray(vertexArrayObject);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); …Run Code Online (Sandbox Code Playgroud) if (call.method.equals("createVideoRenderer")) {
TextureRegistry.SurfaceTextureEntry entry = textures.createSurfaceTexture();
SurfaceTexture surfaceTexture = entry.surfaceTexture();
this.surfaceTexture = surfaceTexture;
Run Code Online (Sandbox Code Playgroud)
这是我的java方法调用,它创建my SurfaceTexture并将其保存到我的类实例中。我一直在阅读有关SurfaceTexture的类,这是我的理解方式:
我需要调用surfaceTexture.setOnFrameAvailableListener(SurfaceTexture.OnFrameAvailableListener listener)以传递SurfaceTexture.OnFrameAvailableListener定义函数的实例onFrameAvailable(SurfaceTexture surfaceTexture)。如果我理解正确,则此函数由调用updateTexImage()。所以我认为onFrameAvailable应该抓取图像并进行渲染?如果是这样,如何在其中调用OpenGL函数?OpenGL上下文在哪里?
我完全不知道如何渲染它。我发现的所有Android OpenGL示例都使用曲面视图或类似的视图。我需要知道如何创建一个纯opengl上下文。
我还认为,当调用onFrameAvailable时,surfaceTexture的纹理将绑定到OpenGL上下文,因此我不需要创建着色器,调整纹理参数等。我只需要对其渲染,也许调用即可glTexImage2D。
那么如何glTexImage2D使用Flutter给我的SurfaceTexture 渲染像红色正方形这样简单的东西呢?
更新:
我发现了这个:https : //github.com/mogol/opengl_texture_widget_example
我成功地通过使用
GLES20.glClearColor(0f, green, 0f, 1f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
Run Code Online (Sandbox Code Playgroud)
但是,我要使用glTeximage2D。我尝试简单地添加
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 100, 100,
0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer);
Run Code Online (Sandbox Code Playgroud)
但这没用
更新:
我进行了一些研究,发现(我认为)android使用gl外部纹理,因此我尝试:
buffer = ByteBuffer.allocate(bufferSize);
for (int i = 0; i < bufferSize; i = …Run Code Online (Sandbox Code Playgroud) 我正在尝试通过 docker 运行 mongorestore 以将数据库恢复到系统上的另一个 dockerized mongo:
sudo docker run --net=host -v $PWD:/home/mongo mongo /bin/bash -c "mongorestore -d venko /home/mongo/mongo_venko_20200326230306.archive"
Run Code Online (Sandbox Code Playgroud)
但我明白了
2020-03-27T00:17:32.645+0000 the --db and --collection args should only be used when restoring from a BSON file. Other uses are deprecated and will not exist in the future; use --nsInclude instead
2020-03-27T00:17:32.645+0000 Failed: file /home/mongo/mongo_venko_20200326230306.archive does not have .bson extension
2020-03-27T00:17:32.645+0000 0 document(s) restored successfully. 0 document(s) failed to restore.
Run Code Online (Sandbox Code Playgroud)
来自mongorestore 错误的答案:不知道如何处理转储文件告诉我传递 -db 选项,但我确实通过了,所以我不知道该怎么做。
我发现了这个:https : //github.com/AndrewGaspar/cmake-cargo但无法让它工作
无论如何,如果我要使用 Makefile 而不是 CMake,我只需创建一个规则来监视 .rs 文件的更改和重新编译。
我找不到从 Cmake 调用 Cargo的解决方案(而不是相反),所以我在这里打开一个。
如何CMakeLists.txt通过调用监视 .rs 文件更改并重新编译cargo build?