Is there any way to get the thumbnail from server side call?
The only method that I researched is:
$.getJSON('http://www.vimeo.com/api/v2/video/' + vimeoVideoId + '.json?callback=?', { format: "json" }, function (data) {
$(".thumbnail").attr('src', data[0].thumbnail_medium);
});
Is there a way to make the same call from code behind? or is there a single URL call like in youtube
img.youtube.com/vi/{0}/0.jpg
List item
I found a way to do this from code behind:
public static string GetVimeoPreviewImage(string videoId)
{
var imageUrl = string.Empty;
try
{
var doc = new XmlDocument();
doc.Load("http://vimeo.com/api/v2/video/" + videoId + ".xml");
var root = doc.DocumentElement;
if (root != null)
{
var selectSingleNode = root.FirstChild.SelectSingleNode("thumbnail_medium");
if (selectSingleNode != null)
{
var vimeoThumb = selectSingleNode.ChildNodes[0].Value;
imageUrl = vimeoThumb;
return imageUrl;
}
}
}
catch (Exception ex)
{
var message = string.Format("{0} Exception: {1}", typeof(VideoHelper).FullName, ex.Message);
Log.Error(message, typeof(VideoHelper));
}
return imageUrl;
}
Related
I downloaded a Youtube downloader from Github it was a WPF and it works however I want to reproduce this C# for Windows App. The original code from WPF is:
public async Task BeginDownload()
{
if (!CheckInputs())
return;
ChangeButtonStates(false);
string link = videoLink.Text;
string? downloadFormat = null;
string savedDirectory = Properties.Settings.Default.savedDirectory;
if (saveMP3.IsChecked == true)
downloadFormat = "mp3";
else
downloadFormat = "mp4";
try
{
cancellationToken = cancellationTokenSource.Token;
// If the given URL contains "&list" it means it is playlist
if (!link.Contains("&list"))
await DownloadSingle(link, savedDirectory, downloadFormat);
else
await DownloadPlaylist(link, savedDirectory, downloadFormat);
}
catch (Exception ex)
{
new Thread(() =>
{
MessageBox.Show($"An error occurred: \"{ex.Message}\".", "Downloader", MessageBoxButton.OK, MessageBoxImage.Error);
}).Start();
}
ChangeButtonStates(true);
}
My code converted for use with windows form
public async Task BeginDownload()
{
if (!CheckInputs())
return;
ChangeButtonStates(false);
string link = videoLink.Text;
string downloadFormat = null;
string savedDirectory = Properties.Settings.Default.savedDirectory;
if (cmbDownloadType.SelectedIndex == 1)
downloadFormat = "mp3";
else
downloadFormat = "mp4";
try
{
cancellationToken = cancellationTokenSource.Token;
//// If the given URL contains "&list" it means it is playlist
//if (!link.Contains("&list"))
await DownloadSingle(link, savedDirectory, downloadFormat);
//else
//await DownloadPlaylist(link, savedDirectory, downloadFormat);
}
catch (Exception ex)
{
new Thread(() =>
{
MessageBox.Show($"An error occurred: \"{ex.Message}\".", "Downloader", MessageBoxButtons.OK, MessageBoxIcon.Error);
}).Start();
}
ChangeButtonStates(true);
}
for simplicity I commented out playlist I can add it later I only want to start with a single download. When I run my code it get a html error not sure how to troubleshoot the error.
WPF code to download single
public async Task DownloadSingle(string link, string path, string format)
{
// Needed for security
var handler = new HttpClientHandler();
var httpClient = new HttpClient(handler, true);
handler.UseCookies = false;
// Get video data
var youtube = new YoutubeClient(httpClient);
var streamData = await youtube.Videos.GetAsync(link);
var title = ReplaceInvalidCharacters(streamData.Title);
var progress = new Progress<double>(value =>
{
// To split the progress bar into two halves, fill one half and then the next,
// maximum of both progress bars is 50
if (downloadProgressOne.Value != 50)
{
downloadProgressOne.Value = value * 100.00f;
}
else
{
downloadProgressTwo.Value = (value * 100.00f) - 50;
}
// Taskbar icon progress bar
taskbarIcon.ProgressValue = value;
downloadStatus.Text = $"Downloading... {Convert.ToInt32(value * 100.00f)}%";
});
try
{
// Download content
await youtube.Videos.DownloadAsync(link, $"{path}\\{title}.{format}", o => o.SetContainer(format).SetPreset(ConversionPreset.UltraFast), progress, cancellationToken);
}
catch (TaskCanceledException)
{
new Thread(() =>
{
MessageBox.Show($"Successfully cancelled the download of: \"{title}\".", "Downloader", MessageBoxButton.OK, MessageBoxImage.Information);
}).Start();
File.Delete($"{path}\\{title}.{format}");
return;
}
catch (Exception ex)
{
new Thread(() =>
{
MessageBox.Show($"Failed to download video: \"{title}\" due to an error.\n\nReason: \"{ex.Message}\".", "Downloader", MessageBoxButton.OK, MessageBoxImage.Warning);
}).Start();
return;
}
new Thread(() =>
{
MessageBox.Show($"Successfully downloaded video: \"{title}\".", "Downloader", MessageBoxButton.OK, MessageBoxImage.Information);
}).Start();
}
public async Task DownloadPlaylist(string link, string path, string format)
{
// Create a string list incase any videos fail to download
List<string> failedVideosTitles = new();
string finalList = "";
int failedVideosAmount = 0;
// Needed for security
var handler = new HttpClientHandler();
var httpClient = new HttpClient(handler, true);
handler.UseCookies = false;
// Get playlist data
var youtube = new YoutubeClient(httpClient);
var playlistData = await youtube.Playlists.GetAsync(link);
var playlistName = ReplaceInvalidCharacters(playlistData.Title);
var total = await youtube.Playlists.GetVideosAsync(link);
var totalNumber = total.Count;
int currentNumber = 0;
// Foreach video in the playlist try to download them as the desired format
await foreach (var video in youtube.Playlists.GetVideosAsync(playlistData.Id))
{
currentNumber++;
var title = ReplaceInvalidCharacters(video.Title);
// Skip download of video if it already exists
if (File.Exists($"{path}\\{title}.{format}"))
{
downloadStatus.Text = $"Skipping {currentNumber}/{totalNumber}...";
await Task.Delay(100);
continue;
}
var progress = new Progress<double>(value =>
{
// To split the progress bar into two halves, fill one half and then the next,
// maximum of both progress bars is 50
if (value < 0.5f || downloadProgressOne.Value < 50)
{
downloadProgressOne.Value = value * 100.00f;
downloadProgressTwo.Value = 0;
}
else
downloadProgressTwo.Value = (value * 100.00f) - 50;
// Taskbar icon progress bar
taskbarIcon.ProgressValue = value;
downloadStatus.Text = $"Downloading... {currentNumber}/{totalNumber} - {Convert.ToInt32(value * 100.00f)}%";
});
try
{
// Download content
await youtube.Videos.DownloadAsync(video.Id, $"{path}\\{title}.{format}", o => o.SetContainer(format).SetPreset(ConversionPreset.UltraFast), progress, cancellationToken);
}
catch (TaskCanceledException)
{
new Thread(() =>
{
MessageBox.Show($"Successfully cancelled the download of playlist: \"{playlistName}\".\n\nFiles have not been deleted.", "Downloader", MessageBoxButton.OK, MessageBoxImage.Information);
}).Start();
File.Delete($"{path}\\{title}.{format}");
return;
}
catch (Exception ex)
{
new Thread(() =>
{
// Increase the failed videos amount by one and add the title to the list
failedVideosAmount++;
failedVideosTitles.Add($"\"{title}\"");
MessageBox.Show($"Skipping download of video: \"{title}\" due to an error.\n\nReason: \"{ex.Message}\".", "Downloader", MessageBoxButton.OK, MessageBoxImage.Warning);
}).Start();
}
}
if (failedVideosAmount != 0)
{
new Thread(() =>
{
// Show a messagebox telling the user it failed to download X amount of videos
MessageBox.Show($"Downloaded playlist: \"{playlistName}\" but failed to download {failedVideosAmount} of the videos.\n\nPress OK to see list of failed videos.", "Downloader", MessageBoxButton.OK, MessageBoxImage.Warning);
// Loop for the length of the string list, build a final string containing
// a list of titles of failed videos then display it in a messagebox for the user
for (int i = 0; i < failedVideosTitles.Count; i++)
{
if (i == 0) { finalList = $"{finalList}{i + 1}. {failedVideosTitles[i]}."; }
else { finalList = $"{finalList}\n\n{i + 1}. {failedVideosTitles[i]}."; }
}
MessageBox.Show(finalList, "Downloader", MessageBoxButton.OK, MessageBoxImage.Information);
}).Start();
}
else
{
new Thread(() =>
{
// The entire playlist was downloaded successfully
MessageBox.Show($"Successfully downloaded playlist: \"{playlistName}\".", "Downloader", MessageBoxButton.OK, MessageBoxImage.Information);
}).Start();
}
}
my converted code
public async Task DownloadSingle(string link, string path, string format)
{
// Needed for security
var handler = new HttpClientHandler();
var httpClient = new HttpClient(handler, true);
handler.UseCookies = false;
// Get video data
var youtube = new YoutubeClient(httpClient);
var streamData = await youtube.Videos.GetAsync(link);
var title = ReplaceInvalidCharacters(streamData.Title);
var progress = new Progress<double>(value =>
{
// To split the progress bar into two halves, fill one half and then the next,
// maximum of both progress bars is 50
if (downloadProgressOne.Value != 50)
{
downloadProgressOne.Value = (int)(value * 100.00f);
}
else
{
downloadProgressTwo.Value = (int)((value * 100.00f) - 50);
}
// Taskbar icon progress bar
//taskbarIcon.ProgressValue = value;
downloadStatus.Text = $"Downloading... {Convert.ToInt32(value * 100.00f)}%";
});
try
{
// Download content
await youtube.Videos.DownloadAsync(link, $"{path}\\{title}.{format}", o => o.SetContainer(format).SetPreset(ConversionPreset.UltraFast), progress, cancellationToken);
}
catch (TaskCanceledException)
{
new Thread(() =>
{
MessageBox.Show($"Successfully cancelled the download of: \"{title}\".", "Downloader", MessageBoxButtons.OK, MessageBoxIcon.Information);
}).Start();
File.Delete($"{path}\\{title}.{format}");
return;
}
catch (Exception ex)
{
new Thread(() =>
{
MessageBox.Show($"Failed to download video: \"{title}\" due to an error.\n\nReason: \"{ex.Message}\".", "Downloader", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}).Start();
return;
}
new Thread(() =>
{
MessageBox.Show($"Successfully downloaded video: \"{title}\".", "Downloader", MessageBoxButtons.OK, MessageBoxIcon.Information);
}).Start();
}
Argh rookie mistake just had to update the nuget package for codepages.
I have the following MVC post.
It post file contents to API.
[HttpPost]
public ActionResult FileUpload_Post()
{
if (Request.Files.Count > 0)
{
var file = Request.Files[0];
using (HttpClient client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
byte[] fileBytes = new byte[file.InputStream.Length + 1]; file.InputStream.Read(fileBytes, 0, fileBytes.Length);
var fileContent = new ByteArrayContent(fileBytes);
fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = file.FileName };
content.Add(fileContent);
var result = client.PostAsync(requestUri, content).Result;
if (result.StatusCode == System.Net.HttpStatusCode.Created)
{
ViewBag.Message= "Created";
}
else
{
ViewBag.Message= "Failed";
}
}
}
}
return View();
}
What if i want to pass additional custom object (preferably json format) along with file contents?
CustomObject obj = new CustomObject;
obj.FirstName = "A";
object.LastName = "B";
Note: Following is Api method that will receive above request.
[HttpPost]
public HttpResponseMessage Upload()
{
if(!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
if (System.Web.HttpContext.Current.Request.Files.Count > 0)
{
var file = System.Web.HttpContext.Current.Request.Files[0];
....
// save the file
....
return new HttpResponseMessage(HttpStatusCode.Created);
}
else
{
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
}
First you need to serialize the CustomObject into json. e.g. using Json.NET
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
Then you could add the jsonString to the MultipartFormDataContent like:
var jsonContent = new StringContent(jsonString);
content.Add(jsonContent, "CustomObject");
In the Upload API method, get the posted json content by
var jsonString = System.Web.HttpContext.Current.Request.Form["CustomObject"];
If the API project has a reference to class CustomObject, you could deserialize the jsonString with:
var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<CustomObject>(jsonString);
If not, you could also deserialize it to a dynamic object:
var obj = Newtonsoft.Json.Linq.JObject.Parse(jsonString);
I am having trouble trying to retrieve large datasets from Azure TableStorage. After several attempts at trying to get it in one go I have given up and am now using the TableContinuation Token, which is now not getting Deserialized correctly.The object is getting created but all the Next... values (i.e. NextRowKey, NextPartitionKey, etc are NULL, when the in stringresponse that gets created you can see the values it should be populating with...
The class I am passing contains a list of objects and the token
public class FlorDataset
{
public List<FlorData> Flors { get; set; }
public TableContinuationToken Token { get; set; }
}
The controller code is not exactly rocket science either....
[HttpGet, Route("api/list/{token}")]
public IHttpActionResult FindAll(string token)
{
try
{
TableContinuationToken actualToken = token == "None"
? null
: new TableContinuationToken()
{
NextPartitionKey = NextPartition,
NextRowKey = token,
NextTableName = NextTableName
};
var x = Run(actualToken);
Flors = x.Flors;
actualToken = x.Token;
NextTableName = actualToken.NextTableName;
NextPartition = actualToken.NextPartitionKey;
return Flors != null
? (IHttpActionResult)new IsoncOkResult<FlorDataset>(x, this)
: NotFound();
}
catch (Exception ex)
{
Trace.TraceError(ex.ToString());
return NotFound();
}
}
private FlorDataset Run(TableContinuationToken token)
{
return _repo.GetAllByYear("2016", token) as FlorDataset;
}
The calling code, which calls my fairly standard Web API 2 Controller is:
do
{
try
{
HttpResponseMessage response = null;
if (string.IsNullOrEmpty(token.NextRowKey))
{
response = await client.GetAsync("api/list/None");
}
else
{
response = await client.GetAsync($"api/list/{token.NextRowKey}");
}
if (response.IsSuccessStatusCode)
{
var stringresponse = await response.Content.ReadAsStringAsync();
var ds = JsonConvert.DeserializeObject<FlorDataset>(stringresponse);
token = ds.Token;
Flors.AddRange(ds.Flors);
}
else
{
token = null;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
token = null;
}
} while (token != null);
Okay, this is not the greatest solution, but it's the only thing that works so far in case anyone else is trying the same and stumbling across my question....
In the calling code bit you do a horrible bit of string replacement before you do the deserialisation.... I actually feel dirty just posting this, so if anyone comes up with a better answer, please feel free to share.....
if (response.IsSuccessStatusCode)
{
var stringresponse = await response.Content.ReadAsStringAsync();
stringresponse = stringresponse.Replace(">k__BackingField", "");
stringresponse = stringresponse.Replace("<", "");
var ds = JsonConvert.DeserializeObject<FlorDataset>(stringresponse);
token = ds.Token;
Flors.AddRange(ds.Flors);
}
Not nice, not pretty, but does work!!!! :-D Going to wash my fingers with bleach now!!!
I've been trying without success today to adapt this example to POST data instead of the example GET that is provided.
http://blogs.msdn.com/b/andy_wigley/archive/2013/02/07/async-and-await-for-http-networking-on-windows-phone.aspx
I've replaced the line:
request.Method = HttpMethod.Get;
With
request.Method = HttpMethod.Post;
But can find no Method that will allow me to stream in the content I wish to POST.
This HttpWebRequest seems a lot cleaner than other ways e.g. sending delegate functions to handle the response.
In Mr Wigley's example code I can see POST so it must be possible
public static class HttpMethod
{
public static string Head { get { return "HEAD"; } }
public static string Post { get { return "POST"; } }
I wrote this class some time ago
public class JsonSend<I, O>
{
bool _parseOutput;
bool _throwExceptionOnFailure;
public JsonSend()
: this(true,true)
{
}
public JsonSend(bool parseOutput, bool throwExceptionOnFailure)
{
_parseOutput = parseOutput;
_throwExceptionOnFailure = throwExceptionOnFailure;
}
public async Task<O> DoPostRequest(string url, I input)
{
var client = new HttpClient();
CultureInfo ci = new CultureInfo(Windows.System.UserProfile.GlobalizationPreferences.Languages[0]);
client.DefaultRequestHeaders.Add("Accept-Language", ci.TwoLetterISOLanguageName);
var uri = new Uri(string.Format(
url,
"action",
"post",
DateTime.Now.Ticks
));
string serialized = JsonConvert.SerializeObject(input);
StringContent stringContent = new StringContent(
serialized,
Encoding.UTF8,
"application/json");
var response = client.PostAsync(uri, stringContent);
HttpResponseMessage x = await response;
HttpContent requestContent = x.Content;
string jsonContent = requestContent.ReadAsStringAsync().Result;
if (x.IsSuccessStatusCode == false && _throwExceptionOnFailure)
{
throw new Exception(url + " with POST ends with status code " + x.StatusCode + " and content " + jsonContent);
}
if (_parseOutput == false){
return default(O);
}
return JsonConvert.DeserializeObject<O>(jsonContent);
}
public async Task<O> DoPutRequest(string url, I input)
{
var client = new HttpClient();
CultureInfo ci = new CultureInfo(Windows.System.UserProfile.GlobalizationPreferences.Languages[0]);
client.DefaultRequestHeaders.Add("Accept-Language", ci.TwoLetterISOLanguageName);
var uri = new Uri(string.Format(
url,
"action",
"put",
DateTime.Now.Ticks
));
string serializedObject = JsonConvert.SerializeObject(input);
var response = client.PutAsync(uri,
new StringContent(
serializedObject,
Encoding.UTF8,
"application/json"));
HttpResponseMessage x = await response;
HttpContent requestContent = x.Content;
string jsonContent = requestContent.ReadAsStringAsync().Result;
if (x.IsSuccessStatusCode == false && _throwExceptionOnFailure)
{
throw new Exception(url + " with PUT ends with status code " + x.StatusCode + " and content " + jsonContent);
}
if (_parseOutput == false){
return default(O);
}
return JsonConvert.DeserializeObject<O>(jsonContent);
}
}
Then when I want to call it, I can use it as following :
JsonSend<User, RegistrationReceived> register = new JsonSend<User, RegistrationReceived>();
RegistrationReceived responseUser = await register.DoPostRequest("http://myurl", user);
I have the following, and it uploads without errors, but the image is always 0 bytes.
Windows Phone App (this is called after selecting or taking a photo):
private void AddImage(PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
string serviceUri = Globals.GreedURL + #"API/UploadPhoto/test5.jpg";
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(serviceUri);
request.Method = "POST";
request.BeginGetRequestStream(result =>
{
Stream requestStream = request.EndGetRequestStream(result);
e.ChosenPhoto.CopyTo(requestStream);
requestStream.Close();
request.BeginGetResponse(result2 =>
{
try
{
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result2);
if (response.StatusCode == HttpStatusCode.Created)
{
this.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Upload completed.");
});
}
else
{
this.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("An error occured during uploading. Please try again later.");
});
}
}
catch
{
this.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("An error occured during uploading. Please try again later.");
});
}
e.ChosenPhoto.Close();
}, null);
}, null);
}
And here is the Web API:
public class UploadPhotoController : ApiController
{
public HttpResponseMessage Post([FromUri]string filename)
{
var task = this.Request.Content.ReadAsStreamAsync();
task.Wait();
Stream requestStream = task.Result;
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve reference to a previously created container.
CloudBlobContainer container = blobClient.GetContainerReference("profilepics");
container.CreateIfNotExists();
var permissions = container.GetPermissions();
permissions.PublicAccess = BlobContainerPublicAccessType.Blob;
container.SetPermissions(permissions);
string uniqueBlobName = string.Format("test.jpg");
CloudBlockBlob blob = container.GetBlockBlobReference(uniqueBlobName);
blob.Properties.ContentType = "image\\jpeg";
blob.UploadFromStream(task.Result);
HttpResponseMessage response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.Created;
return response;
}
}
Any ideas?
Any help would be appreciated.