使用TextureView 内的MediaPlayer 来播放视频,它可以工作。
当一个视频结束并且应该播放另一个视频时,我会调整 TextureView 的大小以适应即将播放的视频的宽高比(例如 - 从 3:4 到 9:16 等等......)。
问题是,第一个视频结束后,它的最后一帧仍然显示,然后调整了TextureView的大小,第一个视频的最后一帧仍然保留了一瞬间,但现在宽高比很差,第二个视频播放得很好。
显示(尺寸 X 尺寸)矩形的视频图像:
图片1:视频1,(3:4):

Image2:视频 1,这里我们位于 2 个视频之间,视频 1 的最后一帧,调整大小后现在位于 (9:16),但矩形看起来很糟糕。下图瞬间显示:

图片 3:视频 2,(9:16),播放良好,但在显示图片 2 片刻后:

所使用的代码没有什么特别的,以下是其中的一些部分:
// To init the TextureView and MediaPlayer:
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
m_MediaPlayer = new MediaPlayer();
m_Surface = new Surface(surfaceTexture);
m_MediaPlayer.setSurface(m_Surface);
}
m_TextureView.setSurfaceTextureListener(this);
// To Resize:
LayoutParams layoutParams = new FrameLayout.LayoutParams(newTVWidth, newTVHeight);
layoutParams.gravity = Gravity.CENTER;
m_TextureView.setLayoutParams(layoutParams);
// To play:
m_MediaPlayer.reset();
m_MediaPlayer.setDataSource(videoFilePath);
m_MediaPlayer.prepare();
// <--- …Run Code Online (Sandbox Code Playgroud) 我在Android应用程序中使用libVLC进行RTSP流式传输.由于视频是通过libView中的SurfaceView加载的,因此我们无法直接拍摄快照.
那么如何使用LibVLC for Android支持快照功能呢?
一种解决方案是通过TextureView加载视频.我们可以使用getBitmap函数使用函数getBitmap()获取当前播放视频的快照.如何在libVLC中添加对textureView的支持?
我已经浏览了源代码VLC.我找到了这个文件snapshot.c.是否可以使用它在Android中启用快照功能?
我有来自android 手册的演示应用程序, 它在我的nexus 4上可以很好地工作,但在Samsung SIII上却无法使用。当应用转到Nexus上的onStop时,我的表面纹理被破坏了。当应用程序转到SIII上的onStop时-我没有对表面纹理进行破坏。仅在onDestroy之后才调用它。
如何在onStop中手动销毁Textureview?
我有一个媒体数据源,我正在使用android播放媒体MediaPlayer.
如何MediaPlayer在同一个视图中显示多个视图的视频输出Activity,有没有其他方法可以做到这一点?
我希望媒体的视频部分能够在两个不同的视图中呈现,而无需从数据源多次读取.
现行代码:
TextureView mTextureView1;
TextureView mTextureView2;
mTextureView1.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mMediaPlayer = new MediaPlayer(AppActivity.this);
try {
mMediaPlayer.setDataSource(getApplicationContext(), Uri.parse(path));
} catch (IOException e) {
e.printStackTrace();
}
mMediaPlayer.setSurface(new Surface(surface));
mMediaPlayer.setLooping(true);
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
}
Run Code Online (Sandbox Code Playgroud) android中VideoView和TextureView以及Suraceview有什么区别?
我什么时候使用每一个?
简单来说,我需要做的就是在Android中显示视频帧的实时流(每帧都是YUV420格式)。我有一个回调函数,我在其中接收单个帧作为字节数组。看起来像这样的东西:
public void onFrameReceived(byte[] frame, int height, int width, int format) {
// display this frame to surfaceview/textureview.
}
Run Code Online (Sandbox Code Playgroud)
一个可行但缓慢的选择是将字节数组转换为位图并绘制到 SurfaceView 上的画布上。将来,我希望能够改变该帧的亮度、对比度等,因此希望我可以使用 OpenGL-ES 来实现同样的目的。我还有哪些其他选择可以有效地做到这一点?
Camera请记住,与或类的实现不同MediaPlayer,我无法将输出定向到表面视图/纹理视图,camera.setPreviewTexture(surfaceTexture);因为我使用 C 中的 Gstreamer 接收单个帧。
我看过很多关于如何使用 Surfaceview 将视频从 android 相机实时流式传输到 rtmp 服务器的示例。一个在这里:https : //github.com/begeekmyfriend/yasea
但是是否可以使用纹理视图将视频从相机流式传输到 rtmp?如果是,我们怎么办?
Textureview mTextureView;
// inside oncreate
mTextureView = (TextureView) findViewById(R.id.texture_view);
mTextureView.setSurfaceTextureListener(AircraftControlActivity.this);
// Outside OnCreate
@Override
public void onSurfaceTextureAvailable(final SurfaceTexture surface, final int width, final int height) {
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
}
@Override
public void onSurfaceTextureUpdated(final SurfaceTexture surface) {
}
Run Code Online (Sandbox Code Playgroud)
接下来做什么?
目前我正在使用相机播放器textureview来渲染我的相机.因为预览可以有任何维度,所以我创建了一些自定义代码来在调用时改变textureview OnSurfaceTextureUpdated:
void updateTextureMatrix(int width, int height) {
Display display = WindowManager.DefaultDisplay;
var isPortrait = (display.Rotation == SurfaceOrientation.Rotation0 || display.Rotation == SurfaceOrientation.Rotation180);
int previewWidth = orgPreviewWidth;
int previewHeight = orgPreviewHeight;
if(isPortrait) {
previewWidth = orgPreviewHeight;
previewHeight = orgPreviewWidth;
}
// determine which part to crop
float widthRatio = (float)width / previewWidth;
float heightRatio = (float)height / previewHeight;
float scaleX;
float scaleY;
if(widthRatio > heightRatio) {
// height must be cropped
scaleX = 1;
scaleY = widthRatio * …Run Code Online (Sandbox Code Playgroud) 我正在使用Camera2API构建相机活动,将拍摄的图像发送到另一个活动.在某些设备上它可以工作,但在其他设备(较慢的设备)上,我得到一个java.lang.IllegalStateException,其中显示"会话已关闭;进一步的更改是非法的".
我在这一行得到了这个异常(在updatePreview()中):
cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, mBackgroundHandler);
Run Code Online (Sandbox Code Playgroud)
这是我的完整代码:
public class NewCamera extends CustomActivity implements TimingActivity {
private static final String TAG = "NewCamera";
private ImageView takePictureButton;
private TextureView textureView;
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
private String cameraId;
protected CameraDevice cameraDevice;
protected CameraCaptureSession cameraCaptureSessions;
protected CaptureRequest.Builder captureRequestBuilder;
private Semaphore mCameraOpenCloseLock = new Semaphore(1);
private Size imageDimension;
private ImageReader imageReader;
private static final int REQUEST_CAMERA_PERMISSION = 200;
private …Run Code Online (Sandbox Code Playgroud) 我无法将纹理绑定到a SurfaceTexture以在Unity中显示.
更新4:基于更新1中的管道(表面 - >外部纹理通过表面纹理 - > fbo - >纹理2d)我知道SurfaceTexture没有正确地将其表面转换为纹理.我可以通过pixelcopy从其表面获得正确的绘制图片,我可以确认我的FBO绘图到texture2d管道使用一些测试颜色.所以问题是,为什么SurfaceTexture不能将其表面转换为纹理?
我Texture在Java中生成一个并将其指针传递回Unity:
public void initGLTexture()
{
Log.d("Unity", "initGLTexture");
int textures[] = new int[1];
GLES20.glGenTextures(1, textures, 0);
mTextureId = textures[0];
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureId);
GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
Run Code Online (Sandbox Code Playgroud)
我SurfaceTexture从id(在Java中)创建一个:
mSurfaceTexture = new SurfaceTexture(mTextureId);
mSurfaceTexture.setDefaultBufferSize(512, 512);
Run Code Online (Sandbox Code Playgroud)
我使用第三方库GeckoView渲染到SurfaceTexture的Surface上.我从Unity调用以下方法OnRenderObject()来保持所有GL渲染在同一个线程上:
mSurfaceTexture.updateTexImage();
Run Code Online (Sandbox Code Playgroud)
我知道上面的代码可以正确地绘制到表面上.
我在Unity中调用以下内容来加载纹理:
_imageTexture2D = Texture2D.CreateExternalTexture(
512,512,TextureFormat.RGBA32,false,true,(IntPtr) mTextureId);
_rawImage.texture = _imageTexture2D;
Run Code Online (Sandbox Code Playgroud)
为什么RawImage应用纹理只显示这个看起来精灵的东西,它应该是一个网页?
更新1:所以我一直在研究以下假设:使用Gecko绘制到Surface,并使用SurfaceTexture将此表面渲染为a GL_TEXTURE_EXTERNAL_OES …
android opengl-es unity-game-engine textureview android-unity-plugin
android ×10
textureview ×10
surfaceview ×3
opengl-es ×2
java ×1
libvlc ×1
playback ×1
rtmp ×1
snapshot ×1
translation ×1
video ×1
xamarin ×1