Monday, November 15, 2010

I Want to Watch Videos in Liferay! Part II

So you've uploaded your videos into the Liferay 5.2 Document Library but now what? How to view them?

Well, one way is to build a portlet.

A little caution here. The video format you choose is going to impact what happens when you try and view it. Different browsers handle this stuff in different ways. One browser might play your content in the designated video viewer while another treats it like a file download. Your best bet is to use a viewer component that plays Flash videos, and stick to those.

So what now?

Choose a component that will display your video. The simplest way is to embed the video object like this:

<object type="application/x-shockwave-flash" style="width: 200px; height: 200px;" data="http://someurl"/>

And there you go.

You can also get a little fancier and use a control like ICEsoft's outputMedia control. It's a little more complicated but you can do a lot more with it programmatically. You can see how it works by going to the ICEfaces website and looking at the Component Showcase.

Then your view page will have markup that looks a little like this:

<ice:outputMedia
id="outputMedia"
player="flash"
source="#{videoDisplay.source}">
<f:param name="play" value="true"/>
</ice:outputMedia>

Again, be aware of your browser and format environment. Choose "windows" as your player to view .wmv files and it'll work great in Internet Explorer, but try it in Chrome and you'll get a download instead. As I said before I strongly recommend Flash here.

The problem is, of course, to know what to put in that source URL. Notice in this second example instead of a hard-coded URL for the source I'm using a JSF reference to a String stored in my backing bean. Why? Because I'm generating the source URL dynamically, based on some configuration options selected by the user. You could hard code a URL in there if you wanted. Personally, I despise hard coding anything. (You could also use a JSF reference for the simpler embedded video object above.)

So how to get at that file?

When you request a document from a Liferay Document Library the URL has to be of a specific structure. Here's an example:

http://localhost:8080/c/document_library/get_file?uuid=67874de5-d480-45d6-82dd-610e9d1a783e&groupId=10136

If you're interested, you can find this value by going into your Document Library portlet, clicking the "Actions" button, and selecting "View." It will display the actual URL of that file.

You can generate this URL programmatically by using the Liferay Service Layer. Here's a simple method to grab those details:

private String getUrl(long selectedFileId){

DLFileEntry file = com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil.getFileEntry(selectedFileId);

return "http://" + hostname + "/c/document_library/get_file?" +
file.getUuid() + "&groupId=" +
file.getGroupId();
}


Notice the hostname isn't hard coded either. That should be a configuration option unless you plan to deploy this portlet on only one server, ever.

"Great!" You say. "But how do I get the file id?"

Well, one way is to browse the folders in the Document Library. Suppose we wanted to choose a video file from a folder in the Document Library named "Previews"

List folderSet;
long selectedFolderId;
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
RenderRequest renderRequest = (RenderRequest) externalContext .getRequest();

long companyId = PortalUtil.getDefaultCompanyId();
(Make sure this goes in a try-catch block.)

folderSet = com.liferay.portlet.documentlibrary.service.DLFolderLocalServiceUtil.getFolders(companyId);
folders = new ArrayList();
for(DLFolder folder : folderSet){
if(folder.getName() .equals("Previews")){
selectedFolderId = folder.getFolderId();
}


Now that you've got the folder you want, you can get the details from each file in it. Let's say we know the name of our video file is "trebuchet.swf" and it's in the folder we found above.

(Make sure this goes in a try-catch block too.)

String videoName = "trebuchet.swf";

DLFileEntry video = com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil.getFileEntry(selectedFolderId, videoName);

now you can use that DLFileEntry object to get the file Id to pass into the method we created above:

getUrl(video.getFileEntryId());

And there you have it. Make sure your component can access it through your backing bean. Maybe initialize your bean with all that code and finish with something like this:

this.source = getUrl(video.getFileEntryId());

Now, I'm not touting this as the very best possible way to do it, and if anybody out there has a better idea please, pass it along. This works, though. So it'll get you results.

In my video portlet, I used ice:selectOneMenu controls to let the user browse the folders in the Document Library, then choose the video file they'd like to view.

No comments:

Post a Comment