如何控制YouTube Flash播放用C#?(How to control the youtube

2019-08-02 09:46发布

我的目标是使可通过全球媒体键来控制的开源的YouTube播放器。 全球主要的问题我把它包括在内,但YouTube播放器之间的通信,我的Windows窗体应用程序只是不适合某些原因。

到目前为止,这是我有:

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>");
}

不幸的是这将返回:

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

我在想什么? 我应该加载不同的网址?
该文件指出,YouTube播放器使用ExternalInterface类从JavaScript或AS3控制它, 它应该与C#的工作 。


更新:


方法用于嵌入播放器: http://www.youtube.com/watch?v=kg-z8JfOIKw

也试图用JavaScript的API WebBrowser控件,但没有运气(球员只是没有到JavaScript命令做出反应,甚至试图设置WebBrowser.url的工作演示 ,都认为我成功是让onYouTubePlayerReady()到使用简单的火灾嵌入对象的版本 )

我觉得可能是我监督,不知道一些安全问题。


更新2:


喜欢的解决方案,请参阅我的回答如下。

Answer 1:

这听起来像你想使用的Adobe Flash为你的界面; 然后通过某些变量恢复到C#。

一个例子是这样的:

在Flash; 创建一个按钮...的ActionScript:

on (press) {
    fscommand("Yo","dude");
}

然后,Visual Studio中,你只需要添加COM对象的引用:冲击波Flash对象

然后嵌入设置为true;

然后,在Visual Studio中,你应该能够进入属性; 找到的fscommand。 该FSCommand将让你的价值从Flash影片物理连接。

AxShockwaveFlashObjects._IShockwaveFlashEvents_FSCommandEvent 

收集; 然后只使用e.commande.arg例如有收集的项目做一些事情。

然后将其添加到事件处理程序;

lbl_Result.Text="The "+e.args.ToString()+" "+e.command.ToString()+" was clicked";

和吊杆它的发射在从Flash数据到Visual Studio。 无需任何疯狂的困难插座。

在一个侧面说明; 如果你有闪光灯在Visual Studio中,关键是要确保它的“嵌入设置为true。” 这将举办Flash对象中的所有路径引用; 以避免任何miscalling到不正确的路径。

我不知道如果是这样的回答你的追求; 或回答您的问题。 但是,如果没有你的目标/错误的详细信息。 我不能帮助你。

希望这可以帮助。 第一部分其实应该告诉你嵌入您的冲击波到Visual Studio中的最佳途径。

请务必添加正确的参考:

  1. 里面打开项目“解决方案资源管理”
  2. 右键点击“添加引用”
  3. 转到“COM对象”

找到合适的对象;

COM Objects:
Shockwave ActiveX
Flash Accessibility
Flash Broker
Shockwave Flash

希望帮助。

这听起来像你没有正确地将其嵌入; 这样你就可以拨打电话吧。 如果我稍微错; 或者是你的意思是这是什么:

如果有困难你RYK过一段时间后回; 有一种方法嵌入YouTube视频:

<% MyYoutubeUtils.ShowEmebddedVideo("<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/gtNlQodFMi8&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><embed src="http://www.youtube.com/v/gtNlQodFMi8&hl=en&fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"></embed></object>") %>

要么...

public static string ShowEmbeddedVideo(string youtubeObject)
{
    var xdoc = XDocument.Parse(youtubeObject);
    var returnObject = string.Format("<object type=\"{0}\" data=\{1}\"><param name=\"movie\" value=\"{1}\" />",
        xdoc.Root.Element("embed").Attribute("type").Value,
        xdoc.Root.Element("embed").Attribute("src").Value);
    return returnObject;
}

你可以在这里找到线索: https://stackoverflow.com/questions/2547101/purify-embedding-youtube-videos-method-in-c-sharp

如果我的帖子出现支离破碎我道歉; 但我不能告诉如果是引用,变量,方法,或嵌入这是造成你的困难。 真心希望这会有所帮助; 或者给我更多的细节,我会相应地调整我的反应。


C#为ActionScript通讯:

import flash.external.ExternalInterface;
ExternalInterface.addCallback("loadAndPlayVideo", null, loadAndPlayVideo);
function loadAndPlayVideo(uri:String):void
{
       videoPlayer.contentPath = uri;
}

然后,在C#; 添加ActiveX控件的实例,并添加内容到一个构造函数。

private AxShockwaveFlash flashPlayer;
public FLVPlayer ()
{

      // Add Error Handling; to condense I left out.
      flashPlayer.LoadMovie(0, Application.StartupPath + "\\player.swf");
}

fileDialog = new OpenFileDialog();
fileDialog.Filter = "*.flv|*.flv";
fileDialog.Title = "Select a Flash Video File...";
fileDialog.Multiselect = false;
fileDialog.RestoreDirectory = true;

if (fileDialog.ShowDialog() == DialogResult.OK)
{
     flashPlayer.CallFunction("<invoke" + " name=\"loadAndPlayVideo\" returntype=\"xml">       <arguements><string>" + fileDialog.FileName + "</string></arguements></invoke>");
}

ActionScript中传播到C#:

import flash.external.ExternalInterface;
ExternalInterface.call("ResizePlayer", videoPlayer.metadata.width, videoPlayer.metadata.height);

flashPlayer.FlashCall += new _IShockwaveFlashEvents_FlashCallEventHandler(flashPlayer_FlashCall);

那么XML应该出现:

<invoke name="ResizePlayer" returntype="xml">
     <arguements>
            <number> 320 </number>
            <number> 240 </number>
     </arguments>
</invoke>

然后解析在事件处理程序的XML和本地调用C#的功能。

 XmlDocument document = new XmlDocument();
    document.LoadXML(e.request);
    XmlNodeList list = document.GetElementsByTagName("arguements");
    ResizePlayer(Convert.ToInt32(list[0].FirstChild.InnerText),   Convert.ToInt32(list[0].ChildNodes[1].InnerText));

现在,它们都传递数据来回。 这是一个基本的例子; 但通过利用ActionScript中传播你不应该使用本机API的任何问题。

希望是更有帮助。 您可以扩大这个想法被重用的实用程序类。 显然,上面的代码有一定的局限性; 但希望它指向你在正确的方向。 是你试图去那个方向? 还是我仍然错过了这一点?


创建一个新的Flash动画; 在ActionScript 3.然后在初始第一框架上; 适用于以下:

Security.allowDomain("www.youtube.com");
var my_player:Object;
var my_loader:Loader = new Loader();

my_loader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3"))
my_loader.contentLoaderInfo.addEventListener(Event.INIT, onLoaderInit);

function onLoaderInit(e:Event):void{
addChild(my_loader);
my_player = my_loader.content;
my_player.addEventListener("onReady", onPlayerReady); 
} 

function onPlayerReady(e:Event):void{
my_player.setSize(640,360);
my_player.loadVideoById("_OBlgSz8sSM",0);
} 

那么究竟是那个脚本做什么的? 它是利用本地API和使用ActionScript通信。 所以,下面我将打破每一行。

Security.allowDomain("www.youtube.com");

如果没有该行YouTube不会与对象交互。

var my_player:Object;

你不能只是影片加载到电影; 因此,我们将创建一个变量对象 。 你必须加载一个特殊的.swf文件将包含访问这些代码。 下面; 做到了这一点。 所以,你可以访问API。

var my_loader:Loader = new Loader();
my_loader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3")); 

我们现在每参考其文档的谷歌API。

my_loader.contentLoaderInfo.addEventListener(Event.INIT, onLoaderInit);

但实际上为了与我们的工作对象; 我们需要等待它被完全初始化。 所以事件监听器将等待; 所以,我们知道我们可以通过命令来了。

onLoaderInit功能将在初始化时被触发。 然后,它的首要任务将是my_loader使得视频似乎显示列表。

所述addChild(my_loader); 是什么将加载一个; 所述my_player = my_loader.content; 将存储,方便接入对象的引用。

虽然它已经被初始化; 你必须进一步等待......你用my_player.addEventListener("onReady", onPlayerReady); 等待和倾听那些自定义事件。 这将使以后的函数来处理。

现在玩家准备的基本配置;

function onPlayerReady(e:Event):void{
my_player.setSize(640,360);
} 

上述功能开始很基本的操作。 然后最后一行my_player.loadVideoById("_OBlgSz8sSM",0); 被引用特定的视频。

然后在你的舞台; 您可以创建两个按钮和应用:

play_btn.addEventListener(MouseEvent.CLICK, playVid); 
function playVid(e:MouseEvent):void { 
my_player.playVideo(); 
} 
pause_btn.addEventListener(MouseEvent.CLICK, pauseVid); 
function pauseVid(e:MouseEvent):void { 
my_player.pauseVideo();
}

这会给你一个播放和暂停功能。 一些额外的项目,你可以使用我们的:

loadVideoById() 
cueVideoById() 
playVideo() 
pauseVideo() 
stopVideo() 
mute()
unMute()

请记住那些不能使用或调用,直到它已完全初始化。 但是使用; 与早期的方法应该让你布局的目标,实际上在二者之间传递变量进行操纵。

希望帮助。



Answer 2:

我想通过确保JavaScript可以谈谈您的Flash应用程序启动。

请确保您有: allowScriptAccess="sameDomain"的嵌入(从设定http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html#includeExamplesSummary )。

您应该验证HTML的“FLASH作品; 然后C-> HTML; 并逐步工作提高到C->你管组件。 你现在有很多C和你管成分之间潜在的故障点,并且很难解决所有这些问题在同一时间。



Answer 3:

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

看来, Error HRESULT E_FAIL...发生在闪光灯这么想的了解所请求的闪光通话。 另外对于YouTube的外部API工作, JS API需要启用:

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

正如我在质询时说整个程序是开源的,所以你会发现在全码到位桶 。
任何意见,建议或合作者的高度赞赏。

完整的解决方案:

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

继后的视频教程 ,Flash Player的设置FlashCall事件将处理急骤> C#的互动功能(在我的例子很YTplayer_FlashCall

生成的`的InitializeComponent()`应该是:

...
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事件处理程序

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;
    }
}

这将解决急骤> C#通信

调用闪光外部函数(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添加事件处理程序:

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");
}

使用前:

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

功能YTplayer_CallFlashYTplayer_FlashCall应该工作用于与像微小调整任何闪光-C#通信YTplayer_CallFlash的开关(命令)。



Answer 4:

这难倒我了数个小时。

只需添加使JS给你的网址:

http://www.youtube.com/v/9bZkp7q19f0?version=3 &enablejsapi = 1

CallFunction现在对我来说工作得很好! 另外在通话中删除不需要的空间。



文章来源: How to control the youtube flash player with c#?