views:

53

answers:

2

I am using .NET to create a video uploading application. Although it's communicating with YouTube and uploading the file, the processing of that file fails. YouTube gives me the error message, "Upload failed (unable to convert video file)." This supposedly means that "your video is in a format that our converters don't recognize..."

I have made attempts with two different videos, both of which upload and process fine when I do it manually. So I suspect that my code is a.) not encoding the video properly and/or b.) not sending my API request properly.

Below is how I am constructing my API PUT request and encoding the video:

Any suggestions on what the error could be would be appreciated.

Thanks

P.S. I'm not using the client library because my application will use the resumable upload feature. Thus, I am manually constructing my API requests.

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

Code:

            // 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
A: 

I don't know what format YouTube is looking for, but if it's a format that should be recognizable on your Windows system, I suggest you save your converted video to a file on disk, then try to open it.

John Saunders
A: 

The send request in done in 2 parts... You send the header, including the size of the video as you have... YouTube responds with a url, and you send the video to that url.. Looks like you are trying to send all in one request. Something a bit like this.

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
JohnnyJP