The app I’m working on could be given a little “oomph” by being able to stream media files from SkyDrive, so I looked in to it.
I currently have a snipped of code that gets the downloadable URL for a SkyDrive file and uses that in some operations, but I’d seen an article on WindowsPhoneGeek (which redirects to here) that made me think this wouldn’t work for streaming.
The basic problem/solution is this: SkyDrive “source” links point to a URL that is redirected and finally lands at the actual location of the file. The problem, then, is that you can’t just pop that source link open in a Media Player instance and have it play; it’ll die upon the redirection. So the proposed solution is to fire up a WebBrowserTask, set the URL to the source link, and capture NavigationCompleted events until you get to the final one, then use that URL to get the location for the media stream and feed that to the player.
Seriously? F that.
I took my snipped of code, slapped its result in the Media Player, and whaddya know. It worked fine.
So I bestow upon you SkyDrive programmers this little nugget. Keep in mind that since I started programming I’ve for some reason loved parsing strings and cutting them up with all sorts of mechanisms. I don’t know why, it just really makes me smile.
public static class SkyDrive { public static string GetDirectDownloadUrl(string sourceUrl) { var colonParts = sourceUrl.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries); var lastPart = colonParts[colonParts.Length - 1]; int posOfLastSlash = lastPart.LastIndexOf('/'); string filename = lastPart.Substring(posOfLastSlash + 1); int posOfLastComma = colonParts[1].LastIndexOf(','); var postProtocolLegitLocation = colonParts[1].Substring(0, posOfLastComma != -1 ? posOfLastComma : colonParts[1].Length); string urlOfFile = string.Join(":", colonParts[0], postProtocolLegitLocation); // Now we have the proper URL to the file. But the filename might have some bad characters posOfLastSlash = urlOfFile.LastIndexOf('/'); filename = urlOfFile.Substring(posOfLastSlash + 1); var baseUrl = urlOfFile.Substring(0, posOfLastSlash); urlOfFile = string.Concat(baseUrl, '/', HttpUtility.UrlEncode(filename)); return urlOfFile; } }
I’m not going to go in to WHY this works, but know that I’ve tested it for photos, videos, and audio on my SkyDrive and haven’t had a single issue. If you want to see why it works, just throw the Source property from a SkyDrive object in to the code and step through it.
You’re welcome.
P.S. If you have a particular Source link that this DOESN’T work with, by all means contact me, comment or tweet, I’d love to see it and make this bad boy work for it as well!