If you would like to discuss anything, please contact me via email: Howard.Bayliss@sequence.co.uk

Friday, June 8, 2012

WMPLib Artist Blank

I'm using SharePoint to host music tracks, which I play with Windows Media Player (WMP).

The player is controlled via WMPLib - Microsoft's WMP API.

I found that I can add SharePoint music files to a WMP playlist via the API, and that the tracks are played. However, when I wanted to display information about the current track (track name, artist, duration, etc), I found that the artist property was empty.

I discovered the fix for this was to URL encode the URL of the track (as it exists in SharePoint) before adding it to the playlist. This was because the track URLs contained spaces (and potentially other odd characters).

Wednesday, June 6, 2012

SharePoint mp3 Headers

Music tracks include header information such as artist, album, duration, etc

In SharePoint Foundation 2010, I wanted to extract this header data and use it to populate library metadata.

To do this, I first downloaded TagLib.

The clever bit about TagLib is that you can create your own SharePoint-specific implementation of the TagLib.File.IFileAbstraction interface. I then used this in a SharePoint event receiver to extract the header data when a user uploads a music file.

Note that this works for other types of music tracks, not just mp3.

The following code shows the code I created for a class that implements IFileAbstraction:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.SharePoint;

namespace Redweb.Redio.Audio
{
public class SharePointMediaFile : TagLib.File.IFileAbstraction
{
private string _fileUrl = String.Empty;

public string FileUrl
{
get
{
return _fileUrl;
}
set
{
_fileUrl = value;
}
}

void TagLib.File.IFileAbstraction.CloseStream(System.IO.Stream stream)
{
if (stream == null)
throw new ArgumentNullException("stream");
stream.Close();
}

string TagLib.File.IFileAbstraction.Name
{
get { return _fileUrl; }
}

System.IO.Stream TagLib.File.IFileAbstraction.ReadStream
{
get
{
MemoryStream outputSteam = null;
using (SPSite site = new SPSite(_fileUrl))
{
using (SPWeb web = site.OpenWeb())
{
if ((web == null) || (web.Exists == false))
{
throw new Exception("No web exists.");
}
SPFile file = web.GetFile(_fileUrl);
if ((file == null) || (file.Exists == false))
{
throw new Exception("No file exists.");
}
byte[] bytes = file.OpenBinary();
outputSteam = new MemoryStream(bytes);
}
}

return outputSteam;
}
}

System.IO.Stream TagLib.File.IFileAbstraction.WriteStream
{
get { throw new NotImplementedException(); }
}
}
}

Thursday, January 5, 2012

SharePoint Stackoverflow

I've recently started to answer SharePoint questions on Stackoverflow / Stackexchange . Hopefully I'll be able to help out some people.

Here are my blog posts related to SharePoint development. I also design and build SharePoint server farms. You can find my configuration posts here.

Cheers
Howard

Monday, December 5, 2011

SharePoint Radio Station

We turned SharePoint 2010 into a "Radio Station". Dan Haywood (Microsoft) writes: "This is probably one of the most impressive solutions I have ever seen built on SharePoint 2010"...

My company, Redweb, gives each team the opportunity to work on a Hack Project. We have 33 hours to conceive, build and present an innovative piece of work.

My team choose to create "Redio", a coroporate radio station that allows companies to play and stream live music across the Enterprise. In a nutshell, the solution included:

* Playlist creation - a user can select tracks from Spotify
* Scheduling of Playlists
* Ability to add adverts and "sweepers"
* Streaming of Spotify tracks from a central server to satellite PCs
* Streaming directly to client machines

The project was challenging enough; but we also needed to present to Microsoft. We did this via Lync and anyone from the Microsoft network could see what we did.

Full review by Dan Haywood: http://www.danhaywoodblog.com/2011/12/redweb-hack-day-produces-sharepoint-fis.html

Video of presentation: https://skydrive.live.com/redir.aspx?cid=9b7d796bd3e9e65c&resid=9B7D796BD3E9E65C!1228&parid=9B7D796BD3E9E65C!305&authkey=!AGjG73d414ceqm0


Here's just a couple of examples of the work we did...

* Our Senior Designer Luke produced an outstanding design for a SharePoint custom field.

With this field, end users can select tracks from Spotify using drag-and-drop. The meter allows users to add up to 30 minutes of music to a Playlist. After the Playlist has been created, it can be scheduled to play at a certain time.



* I created a Visual Web Part that shows the track currently playing. This uses the Bing API to dynamically download Album Art for the track.

Wednesday, November 9, 2011

Remove query string from url

I needed to delete the querystring value from a Url. The code I used to do this is right at the end of this post.

First though, here's the reason I needed to do it.

I found that if you call the SPWeb.GetFile method, with a Url that contains a query string, the value of Item for the returned SPFile will be null. Here's an example:


string url = "http://red-hb:8080/TestSite/Pages/Tamar.aspx?x=y";

using (SPSite site = new SPSite(url))
{
using (SPWeb web = site.OpenWeb())
{
SPFile file = web.GetFile(url);
Console.Write(file.Item["Title"]); // Item will be null.
}
}


OK, here's how I removed the query string:


string url = "http://red-hb:8080/TestSite/Pages/Tamar.aspx?x=y";

Uri uri = new Uri(url);

string queryString = uri.Query;

if (String.IsNullOrEmpty(queryString) == false)
{
url = url.Replace(uri.Query, String.Empty);
}

Thursday, November 3, 2011

"This solution contains no resources scoped for a Web application"

I created a SharePoint Solution that contained a single Feature. The Feature had a Receiver which is used to make web.config modifications.

I wanted to target these modifications at specific SharePoint web applications. However, when I ran the following PowerShell command, I got the message: "This solution contains no resources scoped for a Web application".

Install-SPSolution –Identity <WSP NAME>.wsp –WebApplication http://<TARGET APP URL> -GACDeployment -Force

Other people suggest not including the target web application url. I don't want to do this as it will affect all web applications, not just our own.

The workaround I used was to include the Solution assembly within its own package, and mark it as a "SafeControl".

I realise that this not ideal. Do you have a better solution?

The steps I followed were:

1) Open the Project Properties for the Solution, and set "Include Assembly in Package" to "False".

Include Assembly in Package

2) Edit the Package manifest and include the assembly from the project's own output. Add the assembly / namespace as a SafeControl.

Friday, October 28, 2011

SharePoint Anonymous Access

I was trying to change the Anonymous Access settings for a list, as per this screen:


SharePoint Anonymous Access checkboxes

However, when I checked the "Add Items" box and clicked OK, it did not save the changes. Everytime I repeated this and went back to the screen, the "Add Items" box was not checked.


The cause of the problem was that the Anonymous Policy for the SharePoint Application (that hosted the site) had been changed. By default this is set to "None". However, it had been set to "Deny Write".


SharePoint Anonymous Policy

There wasn't a good reason for this and switching it back to "None" fixed the problem.