使用libVLCsharp来传输受pw保护的IP摄像机视频,但视频无法播放

问题描述

我正在尝试为Onvif投诉设备构建UI。我已经有一段时间在墙上撞头了。我相信我已经正确构建了自定义URI。根据《 ONVIF程序员指南》,我们需要获取配置文件,GetStreamURI和请求流。 http://www.openipcam.com/files/ONVIF/ONVIF_WG-APG-Application_Programmer's_Guide.pdf

使用Wireshark,我相信我看到正在发送HTTP数据包(显示适当的请求),并且我认为这是适当的响应。最终的GetStreamURI从摄像机获得成功的响应。然后,当我尝试调用_mp.Play时,我看到了通过HTTP传输的一些数据包和从摄像机返回的一些TCP数据包。此通信停止后。

using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LibVLCSharp.Shared;
using LibVLCSharp;
using System.ServiceModel.Channels;
using Lib_vlc_CSharp_Onvif.OnvifDevice;
using System.ServiceModel;
using Lib_vlc_CSharp_Onvif.OnvifMedia;


namespace Lib_vlc_CSharp_Onvif
{

    public partial class Form1 : Form
    {
        public LibVLC _libVLC;
        public LibVLCSharp.Shared.MediaPlayer _mp;
        public LibVLCSharp.Shared.Media media; 


        //Todo... make screen size adjustable 
        public System.Drawing.Size VidSize;
        public System.Drawing.Size FormSize;
        public System.Drawing.Point OldVidLoc;


        //Create Onvif Media Profiles through service references 
        OnvifMedia.Media2Client Onvif_media;
        OnvifMedia.MediaProfile[] profiles;

        //Custom URI variable 
        UriBuilder deviceUri; 
        public Form1()
        {
            InitializeComponent();

            //LibVLCSharp Specific 
            Core.Initialize();
            this.KeyPreview = true;

            //Just controlling the size. Todo: Imp controls 
            VidSize = videoView.Size;
            FormSize = this.Size;
            OldVidLoc = videoView.Location;

            //Vlc Specific 
            //Set up the Vlc Lib and then connect the Form1 media window player to the media player of the library.
            //videoVew is vlcsharp item in Form1. 
            _libVLC = new LibVLC();
            _mp = new MediaPlayer(_libVLC);
            videoView.MediaPlayer = _mp;             
        }

        private void button1_Click(object sender,EventArgs e)
        {
            //Set up device to get profiles (Onvif Specific) 

            //required a custom URI and binding. 
            deviceUri = new UriBuilder("Http:/onvif/device_service");
            System.ServiceModel.Channels.Binding binding;
            HttpTransportBindingElement httpTransport = new HttpTransportBindingElement();
            httpTransport.AuthenticationScheme = System.Net.AuthenticationSchemes.Digest;
            binding = new CustomBinding(new TextMessageEncodingBindingElement(MessageVersion.soap12,Encoding.UTF8),httpTransport);

            //Assign IP Address to device URI. Todo: This eventually will be pulled from user entered value in an text Box. 
            deviceUri.Host = "xxx.xxx.x.x";
            DeviceClient Onvif_Device = new DeviceClient(binding,new EndpointAddress(deviceUri.ToString()));
            OnvifDevice.Service[] service = Onvif_Device.GetServices(false);

            //Check if they contain media and that we have made contact Todo wrap in a try catch block
            OnvifDevice.Service xmedia = service.FirstOrDefault(s => s.Namespace == "http://www.onvif.org/ver20/media/wsdl");
            if (xmedia != null)
            {
                Onvif_media = new Media2Client(binding,new EndpointAddress(deviceUri.ToString()));
                Onvif_media.ClientCredentials.HttpDigest.ClientCredential.UserName = "admin";
                Onvif_media.ClientCredentials.HttpDigest.ClientCredential.Password = "admin";
                Onvif_media.ClientCredentials.HttpDigest.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

                //Get camera Profiles. 
                profiles = Onvif_media.GetProfiles(null,null);

                if (profiles != null)
                {
                    foreach (var p in profiles)
                    {
                        listBox.Items.Add(p.Name); 
                        //Profiles listed in Box match profiles setup on camera. 
                    }
                }
            }

            //Eventually add a selection option on the list Box. 
            //listBox.SelectedindexChanged += OnSelectionChanged

            //If we have profiles build a custom URI to past to the vlc boject 
            if (profiles != null)
            {
                //Building URI to pass to VLCSharp VideoView Item.
                //https://www.onvif.org/ver20/media/wsdl/media.wsdl
                //GetSreamUri and define RtspUnicast. 
                //http://www.openipcam.com/files/ONVIF/ONVIF_WG-APG-Application_Programmer's_Guide.pdf on page 57&58

                UriBuilder local_uri = new UriBuilder(Onvif_media.GetStreamUri("RtspUnicast",profiles[0].token));

                //Todo: Build list Box to allow user to switch between profiles. Just past main profile for Now. 

                local_uri.Host = deviceUri.Host;
                local_uri.Port = deviceUri.Port;
                local_uri.Scheme = "rtsp";
                //List full URI info. 
                infoBox.Text = local_uri.Host + local_uri.Port + local_uri.Path; 

                //Past it to VideoView and start playing video. 
                _mp.Play(new Media(_libVLC,local_uri.Uri));
            }
        }
    }
}

更新:我相信我的问题是我建立的URI需要验证。当我将此URI放入网络浏览器时,出现401错误。我不确定为什么在丝鲨鱼上看不到此错误。我将用户名和密码分配给URI对象,但是当我检查“ IsWellFormedURIString”时,出现“无效的端口错误”。

解决方法

您尝试了--rtsp-user和--rtsp-pwd吗?您还可以使用对话框API设置RTSP密码。

如果这不起作用,请共享您的完整日志。

您应该能够将Onvif设备管理器中的URL复制/粘贴到VLC中,并看到它正在播放(前提是您输入了正确的凭据)。如果不是,那已经是一个问题了。

,

您仍然可以分配密码和用户名密码。

MyUri.UserName = MyName
MyUri.Password = password 

当密码中包含“#”之类的字符时,您会遇到问题 虽然我还没有找到解决方法,但是暂时将密码保持为“ MyPassword”之类的简单密码,而不是“ MyPassword#1234”,将允许您将URI与字符串中内置的名称和密码一起使用。>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...