请教:Android正播放视频时的解码输出流如何获取? android视频数据 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 可以通过MediaMetadataRetriever获取到某一帧的Bitmap,感觉这样去做有点不现实……求高手啊 那你直接读这个文件流就可以了啊怎么直接读啊?这个数据流没有存成文件,视频是你自己控制播放呢还是从播放器播放视频的时候截取视频流?这个应该是一样的,我自己控制 的话也是调用系统默认的MediaPlayer解码器, 就是“从播放器播放视频的时候截取视频流”要解码后数据流 最好的应该是从display部分入手,重写一个surfaceview,把这个view传给mediaplayer去播放,这样数据到这个view里面,你先去记录,然后再发出去播放,不过效率上估计有点问题。 那你直接读这个文件流就可以了啊怎么直接读啊?这个数据流没有存成文件,视频是你自己控制播放呢还是从播放器播放视频的时候截取视频流?这个应该是一样的,我自己控制 的话也是调用系统默认的MediaPlayer解码器, 就是“从播放器播放视频的时候截取视频流”要解码后数据流没用过MediaPlayer,但是调用MediaPlayer的话,直接jni处理视频流并描绘图像了,我想应该是取不到了吧 暂时不考虑效率问题,只是要取出数据,跟做个数据拦截一样。原本打开一个视频文件,得到文件的输入流,传递到解码器,解码器进行解码,解码的数据流给Java端SurfaceView绘图;;我现在就是想办法拿到这个数据流,没有传到Java端去绘图(也就是播放器没有画面)也没有关系,这边Java层应用感觉实现不了,不知道JNI能不能实现… 对 c/c++ 不熟额 video播放是在graphic层显示的才能抓,有的方案video直接硬件的layer显示的,这种就没辙了。graphic层可以试下下面两个方法:1,在native层调用mediaplayer,MediaPlayer::setVideoSurfaceTexture接口是传入一个IGraphicBufferProducer,自己建立一个bufferqueue传进去就可以了。2,用virtual display试试看,建立一个虚拟的display。然后仿照surfaceview写一个新的view,把window建立在前面建立的virtual display上。这样输出的数据都在virtual display的buffer中。 在Android4.2/4.4源码上作业应该不存在什么方案吧native层调用是要引入系统库么,需要单独提出来? native调用应该是需要一些系统库,你直接抓一份google代码去编译就是了,就是怕有些权限问题。第二个case在java都有借口,可以试试。 native调用应该是需要一些系统库,你直接抓一份google代码去编译就是了,就是怕有些权限问题。第二个case在java都有借口,可以试试。额小的愚钝,DisplayManager.createVirtualDisplay创建的VirtualDisplay中没有buffer啊?请再指引下… public final class VirtualDisplay { private final DisplayManagerGlobal mGlobal; private final Display mDisplay; private IBinder mToken; VirtualDisplay(DisplayManagerGlobal global, Display display, IBinder token) { mGlobal = global; mDisplay = display; mToken = token; } /** * Gets the virtual display. */ public Display getDisplay() { return mDisplay; } /** * Releases the virtual display and destroys its underlying surface. * <p> * All remaining windows on the virtual display will be forcibly removed * as part of releasing the virtual display. * </p> */ public void release() { if (mToken != null) { mGlobal.releaseVirtualDisplay(mToken); mToken = null; } } @Override public String toString() { return "VirtualDisplay{display=" + mDisplay + ", token=" + mToken + "}"; }}这是VirtualDisplay,内容好少啊,能用吗,不知道怎么用诶? 是不是VirtualDisplay.mDisplay.getMetrics(DisplayMetrics outMetrics),这样应该是需要自己写个播放器了吧? 前面的需求是一样的,生成一个视频文件这边需要编码了,这边可以去看看MediaRecorder 可以先看下virtualdisplaytest.java里面是怎么用的 在解码之后 和 往显示设备上送 之间可以截获这块内存。前者要看framework的解码代码,如果是第2方解码的库,应该有输出的接口。后者在display部分。 可以先看下virtualdisplaytest.java里面是怎么用的……突然发现SurfaceView中没有Surface,这个window怎么搞 可以先看下virtualdisplaytest.java里面是怎么用的……突然发现SurfaceView中没有Surface,这个window怎么搞有的,SurfaceView.getHolder().getSurface() 可以先看下virtualdisplaytest.java里面是怎么用的……突然发现SurfaceView中没有Surface,这个window怎么搞有的,SurfaceView.getHolder().getSurface()现在出现新问题了,DisplayManager.createVirtualDisplay需要API Lv19,目前一般的都是android4.2才Lv17,这怎么办啊 可以先看下virtualdisplaytest.java里面是怎么用的……突然发现SurfaceView中没有Surface,这个window怎么搞有的,SurfaceView.getHolder().getSurface()现在出现新问题了,DisplayManager.createVirtualDisplay需要API Lv19,目前一般的都是android4.2才Lv17,这怎么办啊这没招了....,这条路就走不通了 顶 做过音频的 好像有个 fft的算法 kanbudongle 啊啊啊啊啊啊啊啊啊啊啊 查了下,貌似用SurfaceTexture从video decode里面获取流是最方便的,先去学学怎么用了,大神们 求指导~ 还没有弄出来,这两天看了一下ffmpeg,但是NDK开发太难了,我对C也不懂,先看一下你说的这个 java层的surfacetexture没法获取他的surface,去给meidplayer啊~~~native才有可能 java层的surfacetexture没法获取他的surface,去给meidplayer啊~~~native才有可能什么意思啊,不懂诶? SurfaceTexture好复杂额,暂时还不懂如何实现,但是看那个读取camera图像流的例子是在Java层实现的,其中有几句好像是c++实现的: private final String mVertexShader = "uniform mat4 uMVPMatrix;\n" + "uniform mat4 uSTMatrix;\n" + "attribute vec4 aPosition;\n" + "attribute vec4 aTextureCoord;\n" + "varying vec2 vTextureCoord;\n" + "void main() {\n" + " gl_Position = uMVPMatrix * aPosition;\n" + " vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" + "}\n"; private final String mFragmentShader = "#extension GL_OES_EGL_image_external : require\n" + "precision mediump float;\n" + "varying vec2 vTextureCoord;\n" + "uniform samplerExternalOES sTexture;\n" + "void main() {\n" + " gl_FragColor = texture2D(sTexture, vTextureCoord);\n" + "}\n"; // 略… private int createProgram(String vertexSource, String fragmentSource) { int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); if (vertexShader == 0) { return 0; } int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource); if (pixelShader == 0) { return 0; } int program = GLES20.glCreateProgram(); if (program != 0) { GLES20.glAttachShader(program, vertexShader); checkGlError("glAttachShader"); GLES20.glAttachShader(program, pixelShader); checkGlError("glAttachShader"); GLES20.glLinkProgram(program); int[] linkStatus = new int[1]; GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); if (linkStatus[0] != GLES20.GL_TRUE) { Log.e(TAG, "Could not link program: "); Log.e(TAG, GLES20.glGetProgramInfoLog(program)); GLES20.glDeleteProgram(program); program = 0; } } return program; }这看不懂啊,这些又是在哪里执行的? 另外 rs 文件 跟这个原理是一样的么? 错了错了,弄混乱了有点, 上面那个不是“读取camera图像流的例子”,是另外的一个 SurfaceTexture测试video用的,createProgram对应的俩个参数就是上面的两个字符串,求大神帮忙解释说明下,应该从哪里着手 camera里面有个api,setPreviewTexture来接收surfacetexture,但是mediaplayer没有这样的api的。 camera里面有个api,setPreviewTexture来接收surfacetexture,但是mediaplayer没有这样的api的。能使用SurfaceTexture代替SurfaceView来显示,播放电影应该就可以了吧,能做到吗这样?SurfaceTexture不会用也没有api,google打不开!! camera里面有个api,setPreviewTexture来接收surfacetexture,但是mediaplayer没有这样的api的。能使用SurfaceTexture代替SurfaceView来显示,播放电影应该就可以了吧,能做到吗这样?SurfaceTexture不会用也没有api,google打不开!!都说了,mediplayer没有这样的api camera里面有个api,setPreviewTexture来接收surfacetexture,但是mediaplayer没有这样的api的。能使用SurfaceTexture代替SurfaceView来显示,播放电影应该就可以了吧,能做到吗这样?SurfaceTexture不会用也没有api,google打不开!!下午看了下Surface的api,有个途径可以试下,写一个类似下面的classpublic class LocalHolder implements SurfaceHolder{ SurfaceTexture m_st; Surface m_surface; LocalHolder(SurfaceTexture st){ m_st = st; m_surface = new Suface(m_st); } @Override public Surface getSurface() { return m_surface; } ....//其他接口还需要补全}这样,你建立一个SurfaceTexture初始化后传给用这个texture构造一个LocalHolder出来,然后Mediaplayer.setDisplay就传入LocalHolder对象。 camera里面有个api,setPreviewTexture来接收surfacetexture,但是mediaplayer没有这样的api的。能使用SurfaceTexture代替SurfaceView来显示,播放电影应该就可以了吧,能做到吗这样?SurfaceTexture不会用也没有api,google打不开!!下午看了下Surface的api,有个途径可以试下,写一个类似下面的classpublic class LocalHolder implements SurfaceHolder{ SurfaceTexture m_st; Surface m_surface; LocalHolder(SurfaceTexture st){ m_st = st; m_surface = new Suface(m_st); } @Override public Surface getSurface() { return m_surface; } ....//其他接口还需要补全}这样,你建立一个SurfaceTexture初始化后传给用这个texture构造一个LocalHolder出来,然后Mediaplayer.setDisplay就传入LocalHolder对象。new Surface(m_st);这里需要API14(android4.0) camera里面有个api,setPreviewTexture来接收surfacetexture,但是mediaplayer没有这样的api的。能使用SurfaceTexture代替SurfaceView来显示,播放电影应该就可以了吧,能做到吗这样?SurfaceTexture不会用也没有api,google打不开!!下午看了下Surface的api,有个途径可以试下,写一个类似下面的classpublic class LocalHolder implements SurfaceHolder{ SurfaceTexture m_st; Surface m_surface; LocalHolder(SurfaceTexture st){ m_st = st; m_surface = new Suface(m_st); } @Override public Surface getSurface() { return m_surface; } ....//其他接口还需要补全}这样,你建立一个SurfaceTexture初始化后传给用这个texture构造一个LocalHolder出来,然后Mediaplayer.setDisplay就传入LocalHolder对象。这个API我知道,问题是播放不出来东西 google+ stream里面的滑动切屏效果如何实现 问下编译目标的 user eng 是什么意思阿 ? 想用animation来实现ImageView圆盘自转的效果,有些小问题。 奇思妙想,但无从下手,还望帮助 搜索框显示效果 android gallery问题 activity上监听来电 如何使用root权限来读取文件 关于android sdk更新到4.4.2后 新手学习app 写一段简单的功能 求大神给个小例子 如何改变Fragment的TextView内容 sqlite3
那你直接读这个文件流就可以了啊怎么直接读啊?这个数据流没有存成文件,视频是你自己控制播放呢还是从播放器播放视频的时候截取视频流?这个应该是一样的,我自己控制 的话也是调用系统默认的MediaPlayer解码器, 就是“从播放器播放视频的时候截取视频流”要解码后数据流
那你直接读这个文件流就可以了啊怎么直接读啊?这个数据流没有存成文件,视频是你自己控制播放呢还是从播放器播放视频的时候截取视频流?这个应该是一样的,我自己控制 的话也是调用系统默认的MediaPlayer解码器, 就是“从播放器播放视频的时候截取视频流”要解码后数据流没用过MediaPlayer,但是调用MediaPlayer的话,直接jni处理视频流并描绘图像了,我想应该是取不到了吧
暂时不考虑效率问题,只是要取出数据,跟做个数据拦截一样。
原本打开一个视频文件,得到文件的输入流,传递到解码器,解码器进行解码,解码的数据流给Java端SurfaceView绘图;;我现在就是想办法拿到这个数据流,没有传到Java端去绘图(也就是播放器没有画面)也没有关系,这边Java层应用感觉实现不了,不知道JNI能不能实现… 对 c/c++ 不熟额
graphic层可以试下下面两个方法:
1,在native层调用mediaplayer,MediaPlayer::setVideoSurfaceTexture接口是传入一个IGraphicBufferProducer,自己建立一个bufferqueue传进去就可以了。
2,用virtual display试试看,建立一个虚拟的display。然后仿照surfaceview写一个新的view,把window建立在前面建立的virtual display上。这样输出的数据都在virtual display的buffer中。
第二个case在java都有借口,可以试试。
第二个case在java都有借口,可以试试。额小的愚钝,DisplayManager.createVirtualDisplay创建的VirtualDisplay中没有buffer啊?请再指引下…
private final DisplayManagerGlobal mGlobal;
private final Display mDisplay;
private IBinder mToken; VirtualDisplay(DisplayManagerGlobal global, Display display, IBinder token) {
mGlobal = global;
mDisplay = display;
mToken = token;
}
/**
* Gets the virtual display.
*/
public Display getDisplay() {
return mDisplay;
}
/**
* Releases the virtual display and destroys its underlying surface.
* <p>
* All remaining windows on the virtual display will be forcibly removed
* as part of releasing the virtual display.
* </p>
*/
public void release() {
if (mToken != null) {
mGlobal.releaseVirtualDisplay(mToken);
mToken = null;
}
}
@Override
public String toString() {
return "VirtualDisplay{display=" + mDisplay + ", token=" + mToken + "}";
}
}这是VirtualDisplay,内容好少啊,能用吗,不知道怎么用诶?
后者在display部分。
有的,SurfaceView.getHolder().getSurface()
有的,SurfaceView.getHolder().getSurface()现在出现新问题了,DisplayManager.createVirtualDisplay需要API Lv19,目前一般的都是android4.2才Lv17,这怎么办啊
有的,SurfaceView.getHolder().getSurface()现在出现新问题了,DisplayManager.createVirtualDisplay需要API Lv19,目前一般的都是android4.2才Lv17,这怎么办啊
这没招了....,这条路就走不通了
还没有弄出来,这两天看了一下ffmpeg,但是NDK开发太难了,我对C也不懂,先看一下你说的这个
native才有可能
native才有可能什么意思啊,不懂诶? SurfaceTexture好复杂额,暂时还不懂如何实现,但是看那个读取camera图像流的例子是在Java层实现的,其中有几句好像是c++实现的: private final String mVertexShader =
"uniform mat4 uMVPMatrix;\n" +
"uniform mat4 uSTMatrix;\n" +
"attribute vec4 aPosition;\n" +
"attribute vec4 aTextureCoord;\n" +
"varying vec2 vTextureCoord;\n" +
"void main() {\n" +
" gl_Position = uMVPMatrix * aPosition;\n" +
" vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
"}\n"; private final String mFragmentShader =
"#extension GL_OES_EGL_image_external : require\n" +
"precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform samplerExternalOES sTexture;\n" +
"void main() {\n" +
" gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
"}\n";
// 略…
private int createProgram(String vertexSource, String fragmentSource) {
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
if (vertexShader == 0) {
return 0;
}
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
if (pixelShader == 0) {
return 0;
} int program = GLES20.glCreateProgram();
if (program != 0) {
GLES20.glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
GLES20.glAttachShader(program, pixelShader);
checkGlError("glAttachShader");
GLES20.glLinkProgram(program);
int[] linkStatus = new int[1];
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
if (linkStatus[0] != GLES20.GL_TRUE) {
Log.e(TAG, "Could not link program: ");
Log.e(TAG, GLES20.glGetProgramInfoLog(program));
GLES20.glDeleteProgram(program);
program = 0;
}
}
return program;
}
这看不懂啊,这些又是在哪里执行的? 另外 rs 文件 跟这个原理是一样的么?
createProgram对应的俩个参数就是上面的两个字符串,求大神帮忙解释说明下,应该从哪里着手
都说了,mediplayer没有这样的api
下午看了下Surface的api,有个途径可以试下,写一个类似下面的classpublic class LocalHolder implements SurfaceHolder{
SurfaceTexture m_st;
Surface m_surface;
LocalHolder(SurfaceTexture st){
m_st = st;
m_surface = new Suface(m_st);
}
@Override
public Surface getSurface() {
return m_surface;
} ....//其他接口还需要补全
}这样,你建立一个SurfaceTexture初始化后传给用这个texture构造一个LocalHolder出来,
然后Mediaplayer.setDisplay就传入LocalHolder对象。
下午看了下Surface的api,有个途径可以试下,写一个类似下面的classpublic class LocalHolder implements SurfaceHolder{
SurfaceTexture m_st;
Surface m_surface;
LocalHolder(SurfaceTexture st){
m_st = st;
m_surface = new Suface(m_st);
}
@Override
public Surface getSurface() {
return m_surface;
} ....//其他接口还需要补全
}这样,你建立一个SurfaceTexture初始化后传给用这个texture构造一个LocalHolder出来,
然后Mediaplayer.setDisplay就传入LocalHolder对象。new Surface(m_st);这里需要API14(android4.0)
下午看了下Surface的api,有个途径可以试下,写一个类似下面的classpublic class LocalHolder implements SurfaceHolder{
SurfaceTexture m_st;
Surface m_surface;
LocalHolder(SurfaceTexture st){
m_st = st;
m_surface = new Suface(m_st);
}
@Override
public Surface getSurface() {
return m_surface;
} ....//其他接口还需要补全
}这样,你建立一个SurfaceTexture初始化后传给用这个texture构造一个LocalHolder出来,
然后Mediaplayer.setDisplay就传入LocalHolder对象。这个API我知道,问题是播放不出来东西