5

我正在使用 .NET 创建视频上传应用程序。尽管它正在与 YouTube 通信并上传文件,但该文件的处理失败。YouTube 向我显示错误消息“上传失败(无法转换视频文件)”。据推测,这意味着“您的视频采用我们的转换器无法识别的格式......”

我尝试了两个不同的视频,当我手动进行时,它们都可以正常上传和处理。所以我怀疑我的代码是 a.) 没有正确编码视频和/或 b.) 没有正确发送我的 API 请求。

以下是我构建 API PUT 请求和编码视频的方式:

任何关于错误可能是什么的建议将不胜感激。

谢谢

PS 我没有使用客户端库,因为我的应用程序将使用可恢复上传功能。因此,我手动构建我的 API 请求。

文档:http ://code.google.com/intl/ja/apis/youtube/2.0/developers_guide_protocol_resumable_uploads.html#Uploading_the_Video_File

代码:

            // new PUT request for sending video
            WebRequest putRequest = WebRequest.Create(uploadURL);

            // set properties
            putRequest.Method = "PUT";
            putRequest.ContentType = getMIME(file); //the MIME type of the uploaded video file

            //encode video
            byte[] videoInBytes = encodeVideo(file); 

     public static byte[] encodeVideo(string video)
     {
        try
        {
            byte[] fileInBytes = File.ReadAllBytes(video);
            Console.WriteLine("\nSize of byte array containing " + video + ": " + fileInBytes.Length);
            return fileInBytes;
        }
        catch (Exception e)
        {
            Console.WriteLine("\nException:  " + e.Message + "\nReturning an empty byte array");
            byte [] empty = new byte[0];
            return empty;
        }
     }//encodeVideo

            //encode custom headers in a byte array
            byte[] PUTbytes = encode(putRequest.Headers.ToString());

          public static byte[] encode(string headers)
          {            
              ASCIIEncoding encoding = new ASCIIEncoding();
              byte[] bytes = encoding.GetBytes(headers);
              return bytes;
           }//encode 

            //entire request contains headers + binary video data
            putRequest.ContentLength = PUTbytes.Length + videoInBytes.Length;

            //send request - correct?
            sendRequest(putRequest, PUTbytes);
            sendRequest(putRequest, videoInBytes);

     public static void sendRequest(WebRequest request, byte[] encoding)
    {
        Stream stream = request.GetRequestStream(); // The GetRequestStream method returns a stream to use to send data for the HttpWebRequest.

        try
        {
            stream.Write(encoding, 0, encoding.Length);

        }
        catch (Exception e)
        {
            Console.WriteLine("\nException writing stream: " + e.Message);
        }
     }//sendRequest
4

2 回答 2

0

我不知道 YouTube 正在寻找什么格式,但如果它是一种在您的 Windows 系统上应该可以识别的格式,我建议您将转换后的视频保存到磁盘上的文件中,然后尝试打开它。

于 2010-06-13T08:01:14.117 回答
0

发送请求分两部分完成...您发送标头,包括您拥有的视频大小... YouTube 以 url 响应,然后您将视频发送到该 url.. 看起来您正在尝试在一个请求中发送所有内容。有点像这样的东西。

Try
        Try
            _request = CType(WebRequest.Create(_requestUrl), HttpWebRequest)

            With _request
                .ContentType = "application/atom+xml; charset=UTF-8"
                .ContentLength = _postBytes.Length
                .Method = "POST"
                .Headers.Add("Authorization", String.Format("GoogleLogin auth={0}", MasterAccessToken.ClientLoginToken))
                .Headers.Add("GData-Version", "2")
                .Headers.Add("X-GData-Key", String.Format("key={0}", YouTube.Constants.Security.DEVELOPERKEY))
                .Headers.Add("Slug", filename)
            End With

            _writeStream = _request.GetRequestStream
            With _writeStream
                .Write(_postBytes, 0, _postBytes.Length)
            End With

            Using _response = CType(_request.GetResponse, HttpWebResponse)
                With _response
                    If .StatusCode = HttpStatusCode.OK OrElse .StatusCode = HttpStatusCode.Created Then
                        _ans = _response.Headers("Location")
                    Else
                        Throw New WebException("Cannot get ClientLogin upload location", Nothing, WebExceptionStatus.ProtocolError, _response)
                    End If
                End With
            End Using

        Catch ex As Exception

        Finally
            If _writeStream IsNot Nothing Then
                _writeStream.Close()
            End If

        End Try

        _videoUploadLocation = _ans

        'Got the upload location..... now get the file
        Dim _file As FileInfo = New FileInfo(filename)
        Dim _fileLength As Integer

        Using _fileStream As System.IO.FileStream = _file.OpenRead
            _fileLength = CType(_fileStream.Length, Integer)

            If _fileLength = 0 Then
                Throw New FileLoadException("File appears to be of zero length in UploadVideoFromFileClientLogin:", filename)
            End If

            'create the webrequest
            _request = CType(WebRequest.Create(_videoUploadLocation), HttpWebRequest)

            'No authentication headers needed..
            With _request
                .Timeout = 6000000       'Timeout for this request changed to 10 minutes
                .ReadWriteTimeout = 6000000
                .KeepAlive = True
                .ContentType = "application/octet-stream"
                .ContentLength = _fileLength
                .Method = "POST"
            End With

            'and get the stream
            _writeStream = _request.GetRequestStream

            'And send it over the net
            m_StreamUtils.CancelRequest = False
            m_StreamUtils.SendStreamToStream(_fileStream, _writeStream, AddressOf UploadPogressChanged)
            m_CancelRequest = m_StreamUtils.CancelRequest
        End Using

        If Not (m_CancelRequest) Then

            Using _response = CType(_request.GetResponse, HttpWebResponse)
                With _response
                    If .StatusCode = HttpStatusCode.Created Then
                        _ans = _response.ResponseUri.AbsoluteUri
                    Else
                        Throw New WebException("Cannot get ClientLogin upload location", Nothing, WebExceptionStatus.ProtocolError, _response)
                    End If
                End With
            End Using
        Else
            _ans = String.Empty

        End If

        If _writeStream IsNot Nothing Then
            _writeStream.Close()
        End If
于 2010-10-02T08:22:01.150 回答