- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在实现一项功能,可以在使用 SurfaceView 对象播放 RTMP 流时放大或缩小。我做了一些研究,我决定先计算大小和位置,然后使用 onMeasure() 方法重新构建 View 。
现在我遇到了一个问题,即对象并没有真正遵循我在缩放过程中设置的位置。我想实现的效果是这样的 video (它显示了我的应用程序的 iOS 版本的行为),我记录了 another video 来展示我到目前为止所做的事情。如果我使用与 iOS 版本应用程序相同的位置,对象会更频繁地移动。它一点也不流畅,可能会导致糟糕的用户体验。
我对该行为的观察是,当缩放功能触发时,SurfaceView 的对象将使用固定位置 x 和 y 重新调整其宽度和高度。然后,该对象将向后移动,这可能是由于遵循其父级的布局而导致的。我打印了日志消息,发现当 onMeasure() 被触发时,位置 x 和 y 会发生变化。虽然我在函数中设置了position,但是到onLayout()时还是会发生变化。由于 onLayout() 在 onMeasure() 完成后立即被调用,所以我看不到任何可能的时间来设置位置以避免移动。
以下是我所做的:布局:
<RelativeLayout
android:id="@+id/RelaytiveView"
android:layout_width="fill_parent"
android:layout_height="200dp">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:background="#000000"
android:gravity="center"
android:orientation="vertical" >
<com.player.adapter.RtmpLiveSurfaceview
android:id="@+id/goLiveView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</RelativeLayout>
还有代码:
public class RtmpLiveSurfaceview extends SurfaceView
{
private static final int DEFAULT_PIXEL_WIDTH = 1280;
private static final int DEFAULT_PIXEL_HEIGHT = 720;
private float INIT_WIDTH;
private float INIT_HEIGHT;
private float WIDTH = 0;
private float HEIGHT = 0;
private float SCALER = (float) 1.0;
private float TAG_POINT_X = 0;
private float TAG_POINT_Y = 0;
private float INIT_DIST = 0;
SurfaceHolder mholder;
static final int ZOOM = 2;
@Override
protected void onSizeChanged (int w, int h, int oldw, int oldh)
{
}
@Override
protected void onLayout (boolean changed, int left, int top, int right, int bottom)
{
setX(TAG_POINT_X);
setY(TAG_POINT_Y);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int width = getDefaultSize(DEFAULT_PIXEL_WIDTH, widthMeasureSpec);
int height = getDefaultSize(DEFAULT_PIXEL_HEIGHT, heightMeasureSpec);
if (DEFAULT_PIXEL_WIDTH > 0 && DEFAULT_PIXEL_HEIGHT > 0)
{
if ( DEFAULT_PIXEL_WIDTH * height > width * DEFAULT_PIXEL_HEIGHT )
{
height = width * DEFAULT_PIXEL_HEIGHT / DEFAULT_PIXEL_WIDTH;
}
else if ( DEFAULT_PIXEL_WIDTH * height < width * DEFAULT_PIXEL_HEIGHT )
{
width = height * DEFAULT_PIXEL_WIDTH / DEFAULT_PIXEL_HEIGHT;
}
else
{
}
}
INIT_WIDTH = width;
INIT_HEIGHT = height;
if(WIDTH == 0)
{
WIDTH = INIT_WIDTH;
HEIGHT = INIT_HEIGHT;
}
int wmode = MeasureSpec.getMode(widthMeasureSpec);
int hmode = MeasureSpec.getMode(heightMeasureSpec);
int widthSpec = MeasureSpec.makeMeasureSpec((int)WIDTH, wmode);
int heightSpec = MeasureSpec.makeMeasureSpec((int)HEIGHT, hmode);
setX(TAG_POINT_X);
setY(TAG_POINT_Y);
super.onMeasure(widthSpec, heightSpec);
}
public void init()
{
mholder = getHolder();
mholder.setSizeFromLayout();
mholder.addCallback(new Callback()
{
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
}
});
}
public boolean onTouchEvent(MotionEvent MEvent)
{
switch (MEvent.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_POINTER_DOWN:
{
if(MEvent.getPointerCount() >= 2)
{
mode = ZOOM;
INIT_DIST = spacing(MEvent);
break;
}
}
case MotionEvent.ACTION_MOVE:
{
if (mode == ZOOM)
{
if(MEvent.getPointerCount() >= 2)
{
float newDist = spacing(MEvent);
float tmp_scaler = (float) (((newDist - INIT_DIST) * 0.1 + INIT_DIST) / INIT_DIST);
if((tmp_scaler * WIDTH) > (2.0 * INIT_WIDTH))
tmp_scaler = (float) (((newDist - INIT_DIST) * 0.01 + INIT_DIST) / INIT_DIST);
WIDTH = getWidth();
HEIGHT = getHeight();
if (((tmp_scaler * WIDTH) >= (1.0 * INIT_WIDTH)) && ((tmp_scaler * WIDTH) <= (4.0 * INIT_WIDTH)))
{
SCALER = tmp_scaler;
TAG_POINT_X = getX();
if((TAG_POINT_X + WIDTH * SCALER) < INIT_WIDTH)
TAG_POINT_X = INIT_WIDTH - WIDTH * SCALER;
else if(TAG_POINT_X > 0)
TAG_POINT_X = 0;
TAG_POINT_Y = getY();
if((TAG_POINT_Y + HEIGHT * SCALER) < INIT_HEIGHT)
TAG_POINT_Y = INIT_HEIGHT - HEIGHT * SCALER;
else if(TAG_POINT_Y > 0)
TAG_POINT_Y = 0;
WIDTH = WIDTH * SCALER;
HEIGHT = HEIGHT * SCALER;
requestLayout();
}
}
}
break;
}
}
return true;
}
}
谁能帮帮我?如果无法使用 SurfaceView 实现放大缩小功能,是否有任何建议的解决方案?谢谢。
最佳答案
移动和调整 SurfaceView 的大小可能不是正确的答案。 SurfaceView 的 Surface 部分是一个单独的层,其大小和位置由窗口管理器管理,而不是应用程序的 View 层次结构,因此为 SurfaceView 的属性设置动画往往看起来很糟糕。
一种可能的方法是从 SurfaceView 切换到 TextureView。您可以去掉布局代码,只使用 TextureView 的转换矩阵。例如,请参阅 Grafika 电影播放类中处理视频纵横比的方式的差异 -- PlayMoveSurfaceActivity .clickPlayStop() 使用 AspectFrameLayout,而基于 TextureView 的 PlayMovieActivity .clickPlayStop() 不影响 View ,只调整矩阵。
另一种方法是保留 SurfaceView,但将相机预览发送到 SurfaceTexture 并将输出渲染到 OpenGL ES 纹理。参见 TextureFromCameraActivity举个例子。请注意缩放功能是如何通过更新纹理坐标来实现的。这更加灵活,但您需要合并 GLES 设置代码。
关于android - 如何在 Android 中平滑地实现放大缩小?与带有 RTMP 流的 SurfaceView 相关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28291514/
我需要从 RTMP 流中裁剪视频并将其发送到另一个总是变化的 RTMP 服务器。我的理解是我应该使用 nginx-proxy和 ffmpeg ,谁能帮我设置一下? 我想我需要将流发送到像 /strea
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 6年前关闭。 Improve this qu
如何在gstreamer中混合两个rtmp流? Src: nginx-rtmp 摄像头 - h.264/speex接收器:nginx-rtmp GStreamer 0.10 或 1.0 ------
我正在尝试组合/合并两个 rtmp 流,然后将它们发布到另一个流 例如: ffmpeg -i rtmp://ip:1935/live/micMyStream7 -i rtmp://ip:1935/li
有什么方法可以拒绝用户在其他网站上播放我的流吗?我正在运行带 rtmp 模块的 nginx,ubuntu 13。这是我的 nginx.conf rtmp { server {
已关闭。这个问题是 not about programming or software development 。目前不接受答案。 这个问题似乎不是关于 a specific programming
我正在开发一个使用 SoundManager2 的网络应用程序。在我的头撞到墙上并且没有让我的音乐流式传输之后,我终于在创建新的 SoundManager 声音时切换了一些 URL。 这是我之前使用的
谁能指导我做上面提到的? 基本上我想要的: 将单个视频文件流式传输到 RTMP 服务器(在我的情况下为 nginx)到链接的 python 脚本: rtmp:///stream/ 因此,理想情况下,视
我正在开发一个需要通过 rtmp 协议(protocol)进行实时广播流的 iphone 应用程序。我一直在努力寻找解决方案。我所知道的是我应该能够使用 rtmp-dump。但我是iphone dev
我正在尝试将传入的 rtmp 流保存在我的服务器上作为 mp4 文件。我正在使用 nginx-rtmp模块并从 flv 更改容器至mp4在 exec_record_done指示。这是使用 ffmpeg
这是我尝试运行的脚本,我相信问题出在这里: #!/bin/bash GIF=/home/stream1/85012216.gif STREAM_KEY=thisisasecret URL=rtmp:/
输出视频: https://youtu.be/VxfoBQjoY6E 解释: 我想:在 Opencv 中处理摄像头流并将其推送到 RTMP 服务器。我已经设置了 NGINX(RTMP 模块),并且已经
我正在尝试遵循本指南 - http://www.helping-squad.com/nginx-rtmp-compile-for-windows/ 为 Windows 编译 nginx rtmp,但是
我是这个论坛的新手,我的英语水平不是最好的! 我有一个网站,在那里我发布了摄像机的视频流,以显示在嵌套时间现场发生的事情!一个具有高 IT 技能的人为我构建了一个小服务器用于重新流 (Datarhei
我有一个闪存媒体服务器。我想在 Android 设备中创建一个实时视频聊天应用程序。 我目前正在使用 RTMP 方法来保护我的应用程序,但我不确定 RTMP 是否是保护我的应用程序的正确安全机制?你能
文件结束时如何保持流连接处于事件状态? 我正在使用 ffmpeg 4 我尝试了超时选项,但它不起作用,所以我的例子是: ffmpeg -i input.webm -timeout -f flv rtm
我有一台服务器,目前正在流出 RTMP 媒体,我需要以最小延迟(2-3 秒)播放它。 现在我正在使用 CRTMPServer 来使用流,但是由于没有不依赖 Flash 的 RTMP 播放器,因此该解决
我正在寻找一种解决方案,使用浏览器(Javascript)将笔记本电脑摄像头的数据发送到 rtmp 服务器(如 facebook live 或 youtube)。我做了研究,但没有运气。我得到了什么:
[已解决] -- 最终编辑中的解决方案 我正在使用 ffmpeg 录制 rtmp 直播,并希望添加一个标志,该标志将在新数据停止到达时自动停止处理。 如果我启动和停止脚本(通过按需终止进程来停止),一
我正在尝试从 ubuntu 启动实时(非点播)RTMP 流,但我仅使用 RTSP 成功通过 VLC 流式传输 vlc -vvv ./videos/test.mp4 --sout '#rtp{dst=1
我是一名优秀的程序员,十分优秀!