本文介绍了如何控制YouTube Flash播放用C#?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是使可通过全球媒体的按键来控制一个开源的YouTube播放器。
我知道了覆盖全球的关键问题,但YouTube播放器之间的通信,我的Windows窗体应用程序只是没有出于某种原因。

My goal is to make a open source YouTube player that can be controlled via global media keys.The global key issue I got it covered but the communication between the YouTube player and my Windows Forms application just doesn't work for some reason.

到目前为止,这是我有:

So far this is what I have:

private AxShockwaveFlashObjects.AxShockwaveFlash player;
player.movie = "http://youtube.googleapis.com/v/9bZkp7q19f0"
...
private void playBtn_Click(object sender, EventArgs e)
{
    player.CallFunction("<invoke name=\"playVideo\" returntype=\"xml\"></invoke>");
}



不幸的是这将返回:

Unfortunately this returns:

"Error HRESULT E_FAIL has been returned from a call to a COM component."



我在想什么?我应该加载不同的网址?

规定提供的文档,YouTube播放器使用的 ExternalInterface的类以从JavaScript控制它或AS3所以工作。

What am I missing? Should I load a different URL?
The documentation states that YouTube player uses ExternalInterface class to control it from JavaScript or AS3 so it should work with c#.


方法用于嵌入播放器:

Method used to embed the player: http://www.youtube.com/watch?v=kg-z8JfOIKw

也试过使用的但没有运气(球员只是没有到JavaScript命令做出反应,甚至试图设置 WebBrowser.url 来一个,都认为我成功是获得 onYouTubePlayerReady()使用简单的)

Also tried to use the JavaScript-API in the WebBrowser control but no luck (player just didn't respond to JavaScript commands, tried even to set WebBrowser.url to a working demo, all that I succeeded is to get the onYouTubePlayerReady() to fire using the simple embedded object version )

我觉得可能是因为我负责一些安全问题,不知道。

I think there might be some security issues that I'm overseeing, don't know.


喜欢的解决方案,看看我的下面。

fond solution, see my answer below.

推荐答案

很多后尝试和头部锤击,我已经找到了解决办法:

After a lot of tries and head-hammering, I've found a solution:

似乎错误HRESULT E_FAIL ... 发生在闪光灯这么想的了解所要求的闪存电话。也为YouTube的外部API的工作,需要启用:

Seems that the Error HRESULT E_FAIL... happens when the flash dosen't understand the requested flash call. Also for the youtube external api to work, the js api needs to be enabled:

player.movie = "http://www.youtube.com/v/VIDEO_ID?version=3&enablejsapi=1"

我在提问时表示,整个程序是开源的,所以你会发现在的全部代码。
任何意见,建议或合作者的高度赞赏。



As I said in the question the whole program is open source, so you will find the full code at bitbucket.
Any advice, suggestions or collaborators are highly appreciated.

这里是嵌入,并与YouTube播放器或其它任何Flash对象交互的完整指南。

Here is the complete guide for embedding and interacting with the YouTube player or any other flash object.

之后的
,Flash播放器的的FlashCall 事件设置为函数将处理的 FLASH-> C#的相互作用(在我的例子是 YTplayer_FlashCall

After following the video tutorial, set the flash player's FlashCall event to the function that will handle the flash->c# interaction (in my example it's YTplayer_FlashCall )

...
this.YTplayer = new AxShockwaveFlashObjects.AxShockwaveFlash();
this.YTplayer.Name = "YTplayer";
this.YTplayer.Enabled = true;
this.YTplayer.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("YTplayer.OcxState")));
this.YTplayer.FlashCall += new AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEventHandler(this.YTplayer_FlashCall);
...



的的FlashCall事件处理程序



the FlashCall event handler

private void YTplayer_FlashCall(object sender, AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEvent e)
{
    Console.Write("YTplayer_FlashCall: raw: "+e.request.ToString()+"\r\n");
    // message is in xml format so we need to parse it
    XmlDocument document = new XmlDocument();
    document.LoadXml(e.request);
    // get attributes to see which command flash is trying to call
    XmlAttributeCollection attributes = document.FirstChild.Attributes;
    String command = attributes.Item(0).InnerText;
    // get parameters
    XmlNodeList list = document.GetElementsByTagName("arguments");
    List<string> listS = new List<string>();
    foreach (XmlNode l in list){
        listS.Add(l.InnerText);
    }
    Console.Write("YTplayer_FlashCall: \"" + command.ToString() + "(" + string.Join(",", listS) + ")\r\n");
    // Interpret command
    switch (command)
    {
        case "onYouTubePlayerReady": YTready(listS[0]); break;
        case "YTStateChange": YTStateChange(listS[0]); break;
        case "YTError": YTStateError(listS[0]);  break;
        default: Console.Write("YTplayer_FlashCall: (unknownCommand)\r\n"); break;
    }
}

这将解决在 FLASH-> C#通讯

private string YTplayer_CallFlash(string ytFunction){
    string flashXMLrequest = "";
    string response="";
    string flashFunction="";
    List<string> flashFunctionArgs = new List<string>();

    Regex func2xml = new Regex(@"([a-z][a-z0-9]*)(\(([^)]*)\))?", RegexOptions.Compiled | RegexOptions.IgnoreCase);
    Match fmatch = func2xml.Match(ytFunction);

    if(fmatch.Captures.Count != 1){
        Console.Write("bad function request string");
        return "";
    }

    flashFunction=fmatch.Groups[1].Value.ToString();
    flashXMLrequest = "<invoke name=\"" + flashFunction + "\" returntype=\"xml\">";
    if (fmatch.Groups[3].Value.Length > 0)
    {
        flashFunctionArgs = pars*emphasized text*eDelimitedString(fmatch.Groups[3].Value);
        if (flashFunctionArgs.Count > 0)
        {
            flashXMLrequest += "<arguments><string>";
            flashXMLrequest += string.Join("</string><string>", flashFunctionArgs);
            flashXMLrequest += "</string></arguments>";
        }
    }
    flashXMLrequest += "</invoke>";

    try
    {
        Console.Write("YTplayer_CallFlash: \"" + flashXMLrequest + "\"\r\n");
        response = YTplayer.CallFunction(flashXMLrequest);                
        Console.Write("YTplayer_CallFlash_response: \"" + response + "\"\r\n");
    }
    catch
    {
        Console.Write("YTplayer_CallFlash: error \"" + flashXMLrequest + "\"\r\n");
    }

    return response;
}

private static List<string> parseDelimitedString (string arguments, char delim = ',')
{
    bool inQuotes = false;
    bool inNonQuotes = false;
    int whiteSpaceCount = 0;

    List<string> strings = new List<string>();

    StringBuilder sb = new StringBuilder();
    foreach (char c in arguments)
    {
        if (c == '\'' || c == '"')
        {
            if (!inQuotes)
                inQuotes = true;
            else
                inQuotes = false;

            whiteSpaceCount = 0;
        }else if (c == delim)
        {
            if (!inQuotes)
            {
                if (whiteSpaceCount > 0 && inQuotes)
                {
                    sb.Remove(sb.Length - whiteSpaceCount, whiteSpaceCount);
                    inNonQuotes = false;
                }
                strings.Add(sb.Replace("'", string.Empty).Replace("\"", string.Empty).ToString());
                sb.Remove(0, sb.Length);                       
            }
            else
            {
                sb.Append(c);
            }
            whiteSpaceCount = 0;
        }
        else if (char.IsWhiteSpace(c))
        {                    
            if (inNonQuotes || inQuotes)
            {
                sb.Append(c);
                whiteSpaceCount++;
            }
        }
        else
        {
            if (!inQuotes) inNonQuotes = true;
            sb.Append(c);
            whiteSpaceCount = 0;
        }
    }
    strings.Add(sb.Replace("'", string.Empty).Replace("\"", string.Empty).ToString());


    return strings;
}



加入的Youtube事件处理程序:



adding Youtube event handlers:

private void YTready(string playerID)
{
    YTState = true;
    //start eventHandlers
    YTplayer_CallFlash("addEventListener(\"onStateChange\",\"YTStateChange\")");
    YTplayer_CallFlash("addEventListener(\"onError\",\"YTError\")");
}
private void YTStateChange(string YTplayState)
{
    switch (int.Parse(YTplayState))
    {
        case -1: playState = false; break; //not started yet
        case 1: playState = true; break; //playing
        case 2: playState = false; break; //paused
        //case 3: ; break; //buffering
        case 0: playState = false; if (!loopFile) mediaNext(); else YTplayer_CallFlash("seekTo(0)"); break; //ended
    }
}
private void YTStateError(string error)
{
    Console.Write("YTplayer_error: "+error+"\r\n");
}



的用法例如:



usage ex:

YTplayer_CallFlash("playVideo()");
YTplayer_CallFlash("pauseVideo()");
YTplayer_CallFlash("loadVideoById(KuNQgln6TL0)");
string currentVideoId = YTplayer_CallFlash("getPlaylist()");
string currentDuration = YTplayer_CallFlash("getDuration()");



功能 YTplayer_CallFlash YTplayer_FlashCall 应为任何工作的闪存-C#与像 YTplayer_CallFlash 的开关小的调整(命令)通信。

The functions YTplayer_CallFlash, YTplayer_FlashCall should work for any flash-C# communication with minor adjustments like the YTplayer_CallFlash's switch (command).

这篇关于如何控制YouTube Flash播放用C#?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 03:03