2012-02-09 32 views
1

我修改写在C#中的YouTube下载类使用它在Windows手机上。我的结果如下。但是当我调用dw();我从Web浏览器的文件未找到的异常在行e.Result.Read(缓冲,0,buffer.Length)。我当然知道这意味着什么,但我不知道如何解决它。所以我有两个问题:为什么我的代码不工作?或者有另一种方式在WindowsPhone 7上下载Youtube视频? (如图书馆或免费代码片段...)谢谢。的Youtube类工作不

class YoutubeDownload 
{ 
    string youtubeurl; 
    string fileext; 

    private WebClient webClient = new WebClient(); 

    public void dw() 
    { 
     youtubeurl = "http://www.youtube.com/watch?v=locIxsfpgp4&feature=related"; 
     webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted); 
     webClient.DownloadStringAsync(new Uri(youtubeurl)); 
    } 

    void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) 
    { 
     string rawHtml = e.Result; 
     string getUrl = "http://www.youtube.com/get_video.php?video_id={0}&t={1}"; 
     Regex _titleRegex = new Regex("'VIDEO_TITLE': '(.+)',"); 
     Regex _qualiRegex = new Regex("\"fmt_map\": \"([0-9]{2})"); 
     Regex _idRegex = new Regex("\",\\s*\"t\":\\s*\"([^\"]+)"); 

     Match title = _titleRegex.Match(rawHtml); 
     Match id = _idRegex.Match(rawHtml); 
     Match quali = _qualiRegex.Match(rawHtml); 

     string videotitle = title.Groups[1].Value; 
     string videoid = youtubeurl.Substring(youtubeurl.IndexOf("?v=") + 3); 
     string id2 = id.Groups[1].Value.Replace("%3D", "="); 
     string dlurl = string.Format(getUrl, videoid, id2); 

     fileext = "flv"; 
     if (rawHtml.Contains("'IS_HD_AVAILABLE': true")) // 1080p/720p 
     { 
      dlurl += "&fmt=" + quali.Groups[1].Value; 
      fileext = "mp4"; 
     } 
     else 
     { 
      dlurl += "&fmt=" + quali.Groups[1].Value; 
      if (quali.Groups[1].Value == "18") // Medium 
      fileext = "mp4"; 
      else if (quali.Groups[1].Value == "17") // Mobile 
      fileext = "3gp"; 
     } 
     webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted); 
     webClient.OpenReadAsync(new Uri(dlurl)); 
    } 

    void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) 
    { 
     var file = IsolatedStorageFile.GetUserStoreForApplication(); 
     file.CreateDirectory("YoutubeDownloader"); 

     using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("file." + fileext, System.IO.FileMode.Create, file)) 
     { 
      byte[] buffer = new byte[1024]; 
      while (e.Result.Read(buffer, 0, buffer.Length) > 0) 
      { 
       stream.Write(buffer, 0, buffer.Length); 
      } 
     } 
    } 
} 
+1

除了别的,你的“复制”的方法是不正确 - 你永远*写*'buffer.Length'字节,即使你读过小于... – 2012-02-09 17:34:43

+0

我该怎么办改用? – user1200226 2012-02-09 17:45:37

+0

当你调用'Read',你应该记住的结果,这样,那么你可以使用它在调用写:'而((bytesRead = stream.Read(缓冲,0,buffer.Length))> 0)'。 .. – 2012-02-09 17:46:33

回答

3

当您从结果中的数据复制到独立存储,你总是写缓冲区的全部内容,但多少你读过。你的循环应该是这样的:

using (var stream = new IsolatedStorageFileStream("file." + fileext, 
                FileMode.Create, file)) 
{ 
    byte[] buffer = new byte[1024]; 
    int bytesRead; 
    while ((bytesRead = e.Result.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     stream.Write(buffer, 0, bytesRead); 
    } 
} 

(我没有检查是否这一切都错了,但它听起来像它的帮助...)

声明:我谷歌工作,但我不知道您在YouTube授权方面所做的任何合法性。请不要将此答案当作Google的任何意见表示。就我而言,这个答案纯粹是对一些通用流处理的修复。

+0

继续投资您的401k。 – paislee 2012-02-09 18:31:51