Im having a problem uploading a mp4 file. It should be simple but it fails everytime. If I manually upload it via the browser it works fine. Using the google api following the sample fails.
settings = new YouTubeRequestSettings(_ProductName, _DeveloperKey, _LoginName, _LoginPassword);
request = new YouTubeRequest(settings);
video = new Video();
video.Title = "My Test Movie";
video.Tags.Add(new MediaCategory("Autos", YouTubeNameTable.CategorySchema));
video.Keywords = "cars, funny";
video.Description = "My description";
video.YouTubeEntry.Private = false;
video.Tags.Add(new MediaCategory("mydevtag, anotherdevtag", YouTubeNameTable.DeveloperTagSchema));
video.YouTubeEntry.MediaSource = new MediaFileSource(#"C:\MyFolder\example.mp4", "video/mp4");
videoUpload = request.Upload(video);
if (videoUpload == null)
result = false;
else
it always causes the exception error:
Cannot close stream until all bytes are written.
The request was aborted: The request was canceled.
The file shows up on youtube but has the error:
Failed (unable to convert video file).
The problem is if I upload the same file manually via the browser it works fine.
Any ideas?
Related
I am running an http request and the file is always empty. When I do this on android, it is always working fine, but when I do it on ios, it isn't working.
http.Client client = new http.Client();
var request = await client.get(Uri.parse(url));
var bytes = request.bodyBytes;
String dir = (await getApplicationDocumentsDirectory()).path;
File file = new File('$dir/$name');
file.writeAsBytesSync(bytes);
return file;
That is the code for the get request and returning the file. The file has the contents in my android device, but is null in ios. Can someone help me with this?
I'm working on a local server, experimenting with the YouTube iframe API.
When loading iframes I get the error message "Failed to execute 'postMessage' on 'DOMWindow".
How do I eliminate this error?
I tried the Getting Started in the IFRAME API page and was able to run the sample without a hitch using the python -m SimpleHTTPServer 8080.
Your problem might be related to the way you're using iframe API. Check this SO post for more info.
I think we could customize the sendMessage of the YT.Player
playerOptions.playerVars.origin = window.location.origin or your domain.
this.youtubePlayer = new YT.Player(element,playerOptions);
this.youtubePlayer.sendMessage = function (a) {
a.id = this.id, a.channel = "widget", a = JSON.stringify(a);
var url = new URL(this.h.src), origin = url.searchParams.get("origin");
if (origin && this.h.contentWindow) {
this.h.contentWindow.postMessage(a, origin)
}
}
I used this function to resolve in my project. (Origin answer)
I am using the Xamarin Mono for Android Google API binding. I receive an HTTP 308 error, which is basically a timeout, when I upload a video that's larger than 75 MB. I am unable to cast my videosInsertRequest.RequestFactory to GDataRequestFactory and set the time out. No GDataRequestFactory exists. The request factory is of type ICreateHttp and it's create method returns a HttpWebRequest. Is there another way to set the YouTubeRequest's time out property or upload the videos another way?
GoogleAuthenticator auth2;
YoutubeService yt = new YoutubeService (auth2);
string name = String.Format("{0} {1}", etStatusUpdate.Text, DateTime.Now.ToString());
var videosInsertRequest = yt.Videos.Insert (Helpers.MakeVideo (name, etStatusUpdate.Text), "snippet,statistics,status", MakeVideoFileStream (), VIDEO_FILE_FORMAT);
//((GDataRequestFactory)videosInsertRequest.RequestFactory).Timeout = 9999999;
videosInsertRequest.ProgressChanged += videosInsertRequest_ProgressChanged;
videosInsertRequest.ResponseReceived += videosInsertRequest_ResponseReceived;
I would suggest you to use Data API v3.
YouTube Direct Lite project has uploads for Android.
My customer wants to show progress dialog just as user is uploading video on Youtube.
I write something like:
element = document.forms.uploadNewVideoForm.file;
var fd = new FormData();
console.log(element.files);
fd.append('token', $scope.uploadData.token);
fd.append('file', element.files[0]);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", $scope.uploadProgress, false);
xhr.addEventListener("load", $scope.uploadComplete, false);
xhr.addEventListener("error", $scope.uploadComplete, false);
xhr.addEventListener("abort", $scope.uploadComplete, false);
xhr.open("POST", $scope.uploadData.uploadUrl + '?nexturl=' + encodeURIComponent('http://local.app.com:8000/OK'));
xhr.onreadystatechange = function ( response ) {};
xhr.send(fd);
This code start perfectly, but it fails when Youtube redirects to callback URL.
POST http://uploads.gdata.youtube.com/action/FormDataUpload/<token here>?nexturl=http%3A%2F%2Flocal.app.com%3A8000%2FOK
302 Moved Temporarily
Location: http://local.app.com:8000/OK
Here request interrupts and the error callback is invoked.
Take a look at the following sample (source code). It breaks the upload into two parts:
A CORS request to upload the metadata.
A form POST to upload the actual video.
Unfortunately the upload page doesn't support CORS yet, so this is the best you can do.
I am using Google Data API for .Net(version 1.9) in my application.
I have created a Google apps account and i have set the "Users cannot share documents outside this organization" setting under Google Docs.
When i try to share a file outside of the domain(organization) from Google docs web, i get a error saying the file cannot be shared outside of my domain.
But when i try the same thing from the API, it succeeds. I get a 200 success from the API. When i try to access the file from the share link it says 'You need permission to access this resource'. My question is shouldn't the API return with a error? how can i handle this case?
Here is the code that I am using:
DocumentsRequest request = null;
/* request initialization */
string csBatchReqBody = "<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:gAcl="http://schemas.google.com/acl/2007" xmlns:batch="http://schemas.google.com/gdata/batch"><category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/acl/2007#accessRule"/><entry><id>https://docs.google.com/feeds/default/private/full/document:1DsELtiNwq-ogOrp8cAONdMpGR4gBF79PjijTae-vVNg/acl/user:myusername#mydomain.com</id><batch:operation type="query"/></entry><entry><batch:id>1</batch:id><batch:operation type="insert"/><gAcl:role value="reader"/><gAcl:scope type="user" value="myusername#gmail.com"/></entry>"
string Url = "https://docs.google.com/feeds/default/private/full/document:1DsELtiNwq-ogOrp8cAONdMpGR4gBF79PjijTae-vVNg/acl/batch";
byte[] byteArray = Encoding.ASCII.GetBytes(csBatchReqBody);
MemoryStream inputStream = new MemoryStream(byteArray);
AtomEntry reply = request.Service.Insert(new Uri(Url), inputStream, "application/atom+xml", "");
MemoryStream stream = new MemoryStream();
reply.SaveToXml(stream);
The API actually returns a 400 if you try to share a file outside the domain and the admins have set the "Users cannot share documents outside this organization" flag.
Your code sends a batch request (even if for a single element), you'd have to check the batch response to notice the error.
Instead, use the following code to share a document to a single user, it assumes that entry is the DocumentEntry you want to share:
AclEntry acl = new AclEntry();
acl.Scope = new AclScope("username#gmail.com", "user");
acl.Role = new AclRole("reader");
acl = service.Insert(new Uri(entry.AccessControlList), acl);