fbpx

Recently, we were asked to undertake a piece of work involving O365 Video. The technology has been around for quite a while now and it, certainly for me, has become a core component of the Office365 suite which we’re all now quite comfortable with. Interestingly, while a lot of the other Office365 apps have been the focus of fairly serious development, the simplicity of O365 Video means that there’s not a great deal to do there and when there is, it isn’t particularly well documented. That’s certainly the case we found when we came across a requirement which meant that large videos needed to be uploaded into the video portal from SharePoint.

Fortunately, Microsoft is consistent at documenting their APIs and its business as usual for the Video API:
https://msdn.microsoft.com/en-us/office/office365/api/video-rest-operations

The first thing that we tried was to save the whole file as a binary stream. That works very well, up to a certain point. We started really seeing issues around 250Mb+. Once videos get beyond that size, even the fastest connection struggles a little. Once you start going down the path of slower connections, there’s almost no chance that a large upload will go through.

The other problem that we came across is that with really big files (1Gb+), the browser itself starts to encounter issues. Predictably, Internet Explorer is the first to fall at this hurdle but even Chrome really starts to struggle, even on machines with 16Gb RAM.

Fortunately, Microsoft gives a way to get around these problems. You can upload your file in chunks. These chunks can be of any (reasonable) size, and you can keep sending them until you are done. There are three endpoints which you need to use, ‘StartUpload’, ‘ContinueUpload’ and ‘FinishUpload’. As their names suggest, you need to initiate the whole thing with ‘StartUpload’, call ‘ContinueUpload’ as many times as is needed then send the final chunk with ‘FinishUpload’.

A few things which the documentation doesn’t tell you:

  • You can’t just start an upload. You first must create what is essentially a list item. This list item gives you your ‘videoId’ parameter against which you then upload your video. You also must do this when uploading the file as a single binary stream, too. I like to think of the video as a list item attachment that you can only add once the list item has been created.
  • When you’re uploading a chunk, you must specify where in the file it is, using the ‘offsetSize’ parameter. The documentation says, “If you were uploading 8MB chunks, the offset for the first chunk would be 0, and the offset for the second chunk would be 8*1024=8192”. This is wrong, and MB should in fact be kB.
  • The data which you send has to be a byte array. Not a binary string.
  • The ‘yourGeneratedGuid’ is literally just that. Create your own guid but you must use the same one for all transactions.
  • You can’t upload the chunks simultaneously. You must do this one at a time.

SO HOW DOES IT WORK?

First, you need jQuery. I know I could do without it, but it does make life a lot easier. When you instantiate the object, it really, really wants a channel ID. Without it, it doesn’t know what to do, so think of that as the only ‘required’ parameter.

There are two optional parameters, ‘chunkSize’ and ‘threshold’. chunkSize is the size (in MB) you would like the file to split up into when it is uploaded. The default is 10MB. ‘threshold’ is the point at which the application switches from uploading as a binary stream to chunking. The default for this is 100MB.

If you want to, you can provide a new title and description for the file when it is pushed to the video portal. If not, it just uses the file name.

Then we select our file:

And we can upload it.

The Upload function takes one required parameter, ‘file’. It needs to upload something, after all. The fileOptions is to specify the title and description, as above.

Additionally, there are three functions which you can tie into which are for reporting on how the upload is going and any data that the function has found on its journey.

The first will run on completion only. If it falls over, this won’t execute.

The second reports the percentage completion of the upload.

The third reports which stage the item is at and any additional data that is related to that stage. For example, when it goes to check the channel, it’ll give you back the full channel details.

Here’s what the status reporting (third function) looks like:

And here’s the complete HTML block: