Android 媒体播放器 RTSP

2024-01-09

我正在尝试在 Android 设备上观看 RTSP 流媒体。但是如果服务器设置了流媒体密码,我的 Android 就无法播放它。如果没有密码就可以了。这是我的代码。

public class VideoFragment extends Fragment implements View.OnClickListener, SurfaceHolder.Callback, MediaPlayer.OnPreparedListener {


VideoView m_videoView;
SurfaceView m_surfaceView;
SurfaceHolder m_surfaceHolder;
MediaPlayer m_mediaPlayer;
SharedPreferences m_sharedPref;
Boolean m_videoStarted;

public VideoFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_video, container, false);
    m_sharedPref = this.getActivity().getSharedPreferences(MainActivity.class.getSimpleName(), Context.MODE_PRIVATE);
    m_surfaceView = (SurfaceView) view.findViewById(R.id.surfaceView);
    m_surfaceHolder = m_surfaceView.getHolder();
    m_surfaceHolder.addCallback(this);
    m_surfaceHolder.setFixedSize(320, 240);
    m_videoStarted = false;
    ToggleButton togglePlay = (ToggleButton) view.findViewById(R.id.toggleVideo);
    togglePlay.setOnClickListener(this);
    return view;
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.toggleVideo:
            if(m_videoStarted == false) {
                play();
                m_videoStarted = true;
            }
            else {
                m_mediaPlayer.reset();
            }

            break;
        default:
            Log.i(AppConfig.TAG, "DEFAULT");
            break;
    }
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    Log.e(AppConfig.TAG, "surfaceCreated");

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    m_mediaPlayer.release();
}

@Override
public void onPrepared(MediaPlayer mp) {
    Log.e(AppConfig.TAG, "Media Player Prepared");
    m_mediaPlayer.start();
}

private void play() {
    if(m_mediaPlayer == null) {
        m_mediaPlayer = new MediaPlayer();
    }
    setErrorListener();
    m_mediaPlayer.setDisplay(m_surfaceHolder);
    m_mediaPlayer.setOnPreparedListener(this);
    try {
        Map<String, String> headers =  createHeaders();
        String videoUri = "rtsp://192.168.1.100:554/video/3gpp";
        Log.i(AppConfig.TAG, "Video URI: " + videoUri);
        m_mediaPlayer.setDataSource(getActivity(), Uri.parse(videoUri), headers);
        m_mediaPlayer.prepareAsync();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void setErrorListener() {
    m_mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
            if(extra == MediaPlayer.MEDIA_ERROR_IO) {
                Log.e(AppConfig.TAG, "MEDIA ERROR");
            }
            else if(extra == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
                Log.e(AppConfig.TAG, "SERVER DIED ERROR");
            }
            else if(extra == MediaPlayer.MEDIA_ERROR_UNSUPPORTED) {
                Log.e(AppConfig.TAG, "MEDIA UNSUPPORTED");
            }
            else if(extra == MediaPlayer.MEDIA_ERROR_UNKNOWN) {
                Log.e(AppConfig.TAG, "MEDIA ERROR UNKOWN");
            }
            else if(extra == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
                Log.e(AppConfig.TAG, "NOT VALID PROGRESSIVE PLAYBACK");
            }
            else {
                Log.e(AppConfig.TAG, String.valueOf(what));
                Log.e(AppConfig.TAG, String.valueOf(extra));
                Log.e(AppConfig.TAG, "ERROR UNKNOWN!");
            }
            return false;
        }
    });
}

private Map<String, String> createHeaders() {
    String videoUri = "rtsp://192.168.1.100:554/video/3gpp";

    Map<String, String> headers =  new HashMap<String, String>();
    String camUser = "guest";//m_sharedPref.getString(AppConfig.CAM_USER,"");
    String camPassword = "tseug";//m_sharedPref.getString(AppConfig.CAM_PASSWORD,"");
    String describe = "DESCRIBE " + videoUri + " RTSP/1.0";
    String accept = "application/sdp";
    String basicAuthValue = "";

    if (camUser != "") {
        String credentials = camUser + ":" + camPassword;
        byte[] bytes = credentials.getBytes();
        int flags = Base64.URL_SAFE|Base64.NO_WRAP;
        basicAuthValue = "Basic " + Base64.encodeToString(bytes, flags);
        headers.put("Authorization", basicAuthValue);
    }

    headers.put("Request", describe);
    headers.put("Accept", accept);
    Log.i(AppConfig.TAG, "Describe: " + describe);
    Log.i(AppConfig.TAG, "Authorization: " + basicAuthValue);
    Log.i(AppConfig.TAG, "Accept: " + accept);
    return headers;
}

}

我使用的网络摄像机是D-link DCS 942L。我总是收到摄像头的 401 响应,但我的用户名和密码是正确的。这是我得到的日志

    05-25 21:45:31.640   1917-19687/? W/ARTSPConnection﹕ RTSP Response: 401
05-25 21:45:31.640   1917-19687/? I/MyHandler﹕ DESCRIBE completed with result 0 (Success)
05-25 21:45:31.640   1917-19687/? E/MyHandler﹕ Server responses [401] ERROR for the DESCRIBE request
05-25 21:45:31.645   1917-19687/? W/ARTSPConnection﹕ onReceiveResponse >>> State is not CONNECTED !!!
05-25 21:45:31.665   1917-19685/? V/NuPlayer﹕ scanning sources haveAudio=0, haveVideo=0
05-25 21:45:31.665   1917-19685/? V/MediaPlayerService﹕ [152] notify (0x41c61ca0, 100, 1, -2147483648)
05-25 21:45:31.665  19534-19547/com.cameraalert.app V/MediaPlayer﹕ message received msg=100, ext1=1, ext2=-2147483648
05-25 21:45:31.665  19534-19547/com.cameraalert.app E/MediaPlayer﹕ error (1, -2147483648)
05-25 21:45:31.665  19534-19547/com.cameraalert.app V/MediaPlayer﹕ callback application
05-25 21:45:31.665  19534-19547/com.cameraalert.app V/MediaPlayer﹕ back from callback
05-25 21:45:31.665  19534-19534/com.cameraalert.app E/MediaPlayer﹕ Error (1,-2147483648)
05-25 21:45:31.665  19534-19534/com.cameraalert.app E/CameraAlert﹕ 1
05-25 21:45:31.665  19534-19534/com.cameraalert.app E/CameraAlert﹕ -2147483648
05-25 21:45:31.665  19534-19534/com.cameraalert.app E/CameraAlert﹕ ERROR UNKNOWN!

我想知道我的请求头是否错误。这里有一篇文章http://www.tuicool.com/articles/R7ZF7bF http://www.tuicool.com/articles/R7ZF7bF关于如何使用我使用的同一台相机通过身份验证来播放 RTSP。 我将非常感谢任何帮助或解释。


我和你一样正在开发RTSP相关代码,我发现以下结论:

  1. 使用 MediaPlayer 时,您的 RTSP_URL 可以类似于:rtsp://account:[电子邮件受保护] /cdn-cgi/l/email-protection
  2. 但是对于你提到的身份验证,如果你的相机使用HTTP基本身份验证,你需要在http请求中添加标头:,例如(我使用OKHTTP 2.0):

    String basicAuth = Credentials.basic("账户", "通行证"); 请求 request = new Request.Builder().url(url).header("授权", basicAuth).build(); 响应response = client.newCall(request).execute();

这对我行得通!希望对您有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 媒体播放器 RTSP 的相关文章

  • 如何在红米手机上通过应用程序图标显示徽章数量?

    我可以使用以下代码在三星设备上使用应用程序图标显示徽章计数
  • WifiConfiguration 在 Lollipop 中启用网络

    我正在研究 Wifi 项目 有一个模块可以让用户以编程方式加入 wifi 在 kitkat 及以下版本中它可以成功工作 但在 Lollipop 中它不起作用 这是代码 WifiManager wifiManager WifiManager
  • 启动画面反应本机后出现白屏

    编辑 似乎是因为 MainActivity 加载太重而生成白屏 我设法首先使用本机启动屏幕来解决 然后在本机被杀死后立即基于下一个插件的 js 实现 我做了一些修改完美匹配两个启动画面https github com crazycodebo
  • Android 的 GCM 推送通知[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 最近 我尝试学习 GCM 并制作一个测试应用程序 该应用程序将通过 androids 官方网站获取 an
  • 关于android Sqlite在多进程情况下的安全性

    在我的应用程序中 存在多个进程 并且在每个进程中 我需要访问同一个SQLite数据库 当然 这意味着超过2个线程 所以我不仅担心SQLite的线程安全性 还担心SQLite的线程安全性 还有过程安全 这种情况的一种解决方案是使用内容提供者
  • 如何设置itemTouchHelper选择性滑动?

    所以我在 recyclerview rv 上实现了这个 itemtouchhelper simple 回调 现在 在这个 rv 中 我根据内容类型将 2 种布局设置为一行 因此 当我在 rv 上设置此 touchhelper 时 它正在这两
  • 要在进程中运行 dex,Gradle 守护进程需要更大的堆。目前有 910 MB

    实际上主要错误是 java exe完成非零退出值 1 首先我告诉你安装 studio 后遇到的每个问题 三天前 我刚刚安装了 android studio 并创建了新项目 1 首先它抛出错误 插件太旧 请更新到更新的版本 在谷歌上搜索后我改
  • 如何区分ActionBarSherlock中的两次菜单项点击?

    我最近一直在使用 ActionBarSherlock 并按照各种教程 我编写了这段代码来将项目添加到操作栏 Override public boolean onCreateOptionsMenu Menu menu menu add Ref
  • 无法解析配置“:app:debugRuntimeClasspath”的所有文件。问题

    我的 android studio 遇到了下一个问题 导致 org gradle api internal artifacts ivyservice DefaultLenientConfiguration ArtifactResolveEx
  • Android 可检查子菜单选项

    所以我有一个用于选项菜单项的子菜单 我想要一个可检查条目的列表 用户可以根据需要选择 取消选择多个条目 我无法解决的唯一问题是如何防止单击其中一个复选框时关闭选项菜单 我看到 PerformShortcut 有一个 FLAG PERFORM
  • 如何设置上拉刷新SwipeRefreshLayout

    我看到很多 ListView 下拉刷新的库 但是当从上到下拉动时它们是工作的 但是从下到上拉动时我如何刷新 我可以用这个做吗滑动刷新布局 http developer android com reference android suppor
  • Android 视图上的动态气泡

    任何人都可以如何在Android布局上制作可点击的动态气泡 我的设计师对屏幕的想法如下 我的图像中所有气泡都是分配给用户的一组任务 气泡的标签根据任务而变化 1 1 根据我的项目要求 颜色和半径将根据 api 响应而变化 您能建议任何演示或
  • 无法调整 Android React Native 模块中线性布局子项的大小

    完整代码在这里 https github com sbaar ResizableLLRN 这里有关于 java 中正确行为和 React Native 中错误行为的视频 https drive google com file d 0Bxl2
  • 在 Android 5 上支持 BLE 外设角色的芯片组 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 Android 5 0 Lollipop 引入的新 BLE 外设模式将不会在 Nexus 4 5 或 7 上启用 https code
  • Android Youtube API 可用吗? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有适用于 Android 的 YouTube API 吗 如果不是 除了通过网络浏览器之外 如何从 Yo
  • 未调用内容提供商 query() (Android TV)

    据报道 我正在尝试将我的应用程序纳入 Android TV 全局搜索中文档 http developer android com training tv discovery searchable html我必须创建以下内容 内容提供商 可搜
  • 动画结束后更改视图位置

    我开发了一个基于ViewGroup我的问题是我需要在动画结束后保存项目的位置 我打了电话setFillAfter true 在我创建的动画对象中AnimationListener并在其中onAnimationEnd方法调用View layo
  • 如何在对话框中配置自定义按钮?

    这里我有一个自定义对话框 里面有背景 2 ImageButton 问题是 当我尝试为该按钮设置 onclick 侦听器时 程序将返回 NullPointerException 我不知道为什么会发生这种情况 无论如何如何将操作分配给对话框内的
  • Android进程调度

    我试图更好地理解 以便在创建 Android 应用程序 服务时确定潜在的互操作性问题对可靠性的影响 我想弄清楚进程优先级是如何确定的 服务和活动之间优先级的差异以及调度程序是否以不同方式对待它们的优先级 基本上 我试图深入了解某个活动或服务
  • Android 使用非公历

    我正在创建一个DatePickerDialogFragment用户将在其中选择出生日期 我想确保我可以处理非公历日期 我无法更改在我的设备上使用的日历类型 Android 是否允许用户切换日历类型 如果是的话 步骤是什么 到目前为止我还没有

随机推荐

  • 将基本 Cocoa 应用程序转换为基于文档的应用程序

    我和我的团队一直在开发一个现有的 非基于文档的 Cocoa 应用程序 这是我们的第一个 Cocoa 应用程序 尽管到目前为止我们已经开发了许多 iOS 应用程序 不过 该应用程序确实应该是基于文档的 因此我已经开始尝试对其进行转换 但这里和
  • Sphinx:同一图形可能有不同的相对路径吗?

    我是狮身人面像新手 想在两个不同的版本中显示相同的图形 rst files 第一个 rst 文件 lower rst 与 figures 文件夹位于同一级别 我在其中包含一个图形 如下所示 figure figures figure1 pn
  • 模数除法如何工作

    我不太明白模数除法是如何工作的 我在计算27 16并结束了11我不明白为什么 我似乎无法在网上找到通俗易懂的解释 有人可以详细说明这里发生了什么吗 大多数解释都遗漏了一个重要步骤 让我们用另一个例子来填补空白 鉴于以下情况 Dividend
  • 启动进程的服务不会显示 GUI C#

    嘿 我正在尝试获取服务来启动我的程序 但它没有显示 GUI 该过程开始 但没有显示任何内容 我尝试启用 允许服务与桌面交互 但仍然不起作用 我的程序是一个计算机锁定设备 用于阻止未经授权的用户访问计算机 我正在运行带有 64 位操作系统的
  • 在 Mac 应用程序中执行 AppleScript 文件?

    我正在寻找一种从 Mac 应用程序中执行 Applescript 文件的方法 我以前制作过使用的 mac 应用程序NSAppleScript script NSAppleScript alloc initWithSource MY CODE
  • 识别某人正在玩的游戏而无需聊天(discord bot python)

    不和谐机器人蟒蛇 代码是 如果有人聊天 如果这个人正在玩 守望先锋 他或她将被提升为玩家角色 如果没有 他或她将被删除或什么也不会发生 但我正在寻找一种无需聊天即可识别正在玩的游戏的方法 有人能帮我吗 client event async
  • 在 PHP 中组合图像同时保留透明度

    看看这里 我想删除蓝色部分末端的白色东西 但我尝试了很多不同的方法 但都不起作用 如果需要 可以在以下位置找到 pnghttp tyilo jbusers com PNG http tyilo jbusers com PNG 文件夹 htt
  • Owl Carousel 2 - 如何获取当前物品?

    我正在使用 Owl Carousel 2 开发一个网站 我只想检测哪个项目显示在前面 以前是这样的 http owlgraphic com owlcarousel demos owlStatus html http owlgraphic c
  • 从不同文件夹加载 Jar 文件

    我目前正在制作 Minecraft Mod Loader package spideyzac import java util concurrent CopyOnWriteArrayList import org lwjgl opengl
  • 无法将 Enumerable.Count 与 List 一起使用,编译器假定为 List.Count

    我还没有注意到这种行为 也许是因为我更喜欢 VB NET 中的查询语法并将查询和执行方法拆分为不同的语句 如果我尝试编译以下简单查询 Dim wordList As List Of String New List Of String Dim
  • 如何使用spring mvc使用@RequestParam捕获多个参数?

    假设单击一个超链接并使用以下参数列表触发一个 urlmyparam myValue1 myparam myValue2 myparam myValue3 现在我如何使用捕获所有参数 RequestParam在 Spring MVC 中 我的
  • Firefox/Chrome 上的字体大小和缩进不一致

    Demo http jsfiddle net waitinforatrain 9JU5b http jsfiddle net waitinforatrain 9JU5b I m trying to make a notification i
  • 关于 iOS 本地化

    在以下文档中 http developer apple com library mac documentation MacOSX Conceptual BPInternational Articles LanguageDesignation
  • Maven打包有效pom

    我有一个带有许多子模块的 Maven 项目 其中一些子模块打包为 jar 并部署到 Nexus Maven 存储库 我遇到的问题是打包的 jar 引用了不一定部署的父 pom 有没有办法让Maven部署有效的pom而不是pom xml 您需
  • 使用 Swift 录制视频 avfoundation 时我做错了什么?

    我正在用 AVFoundation 快速录制视频 但看不到 file mp4 我不知道我是否正在录制并且保存得不好 或者我没有录制 因为我可以显示会话预览 所以所有组件都使其功能正确 我的代码是 import UIKit import AV
  • 如何将 Firebase 数据实时更新到 React 应用程序

    我正在开发一个将 Firebase 数据实时更新为 React 的应用程序 我想要做的是 用户更新应用程序中的状态 同时应该为另一个用户更新状态 我已经构建完成 但它不断渲染renderStatus 而且速度太慢了 我想在 RDB 数据更新
  • .NET Math.Round(,,MidpointRounding.AwayFromZero) 无法正常工作

    我使用的是 Visual Studio Professional 2012 我创建了一个新的 C ConsoleApplication 针对 NET Framework 4 5 代码如下 static void Main string ar
  • rake db:create - 找不到 JavaScript 运行时

    这是我得到的错误 sergio sergio VirtualBox blog rake db create rake aborted Could not find a JavaScript runtime See https github
  • MongoDB 范围分页

    据说在记录多的MongoDB集合中使用skip 进行分页速度很慢 不推荐 可以使用范围分页 基于 gt id 比较 db items find id gt ObjectId 4f4a3ba2751e88780b000000 它适合显示上一个
  • Android 媒体播放器 RTSP

    我正在尝试在 Android 设备上观看 RTSP 流媒体 但是如果服务器设置了流媒体密码 我的 Android 就无法播放它 如果没有密码就可以了 这是我的代码 public class VideoFragment extends Fra