Wednesday 27 November 2013

Clearing the SharePoint Configuration Cache

Error message when you try to modify or to delete an alternate access mapping in Windows SharePoint Services 3.0: "An update conflict has occurred, and you must re-try this action"


To resolve this issue, clear the file system cache on all servers in the server farm on which the Windows SharePoint Services Timer service is running. To do this, follow these steps:
1.       Stop the Timer service. To do this, follow these steps:
a.       Click Start, point to Administrative Tools, and then click Services.
b.       Right-click Windows SharePoint Services Timer, and then click Stop.
c.        Close the Services console.
2.       On the computer that is running Microsoft Office SharePoint Server 2007 and on which the Central Administration site is hosted, click Start, click Run, type explorer, and then press ENTER.
3.       In Windows Explorer, locate and then double-click the following folder:
Drive:\Documents and Settings\All Users\Application Data\Microsoft\SharePoint\Config\GUID
Notes
o    The Drive placeholder specifies the letter of the drive on which Windows is installed. By default, Windows is installed on drive C.
o    The GUID placeholder specifies the GUID folder.
o    The Application Data folder may be hidden. To view the hidden folder, follow these steps:
1.       On the Tools menu, click Folder Options.
2.       Click the View tab.
3.       In the Advanced settings list, click Show hidden files and folders under Hidden files and folders, and then click OK.
o    In Windows Server 2008, the configuration cache is in the following location:
Drive:\ProgramData\Microsoft\SharePoint\Config\GUID
4.       Back up the Cache.ini file.
5.       Delete all the XML configuration files in the GUID folder. Do this so that you can verify that the GUID folder is replaced by new XML configuration files when the cache is rebuilt.

Note When you empty the configuration cache in the GUID folder, make sure that you do not delete the GUID folder and the Cache.ini file that is located in the GUID folder.
6.       Double-click the Cache.ini file.
7.       On the Edit menu, click Select All.
8.       On the Edit menu, click Delete.
9.       Type 1, and then click Save on the File menu.
10.    On the File menu, click Exit.
11.    Start the Timer service. To do this, follow these steps:
 .         Click Start, point to Administrative Tools, and then click Services.
a.       Right-click Windows SharePoint Services Timer, and then click Start.
b.       Close the Services console.
Note The file system cache is re-created after you perform this procedure. Make sure that you perform this procedure on all servers in the server farm.
12.    Make sure that the Cache.ini file has been updated. For example it should no longer be 1 if the cache has been updated.
13.    Click Start, point to Programs, point to Administrative Tools, and then click SharePoint 3.0 Central Administration.
14.    Click the Operations tab, and then click Timer job status under Global Configuration.
15.    In the list of timer jobs, verify that the status of the Config Refresh entry is Succeeded.
16.    On the File menu, click Close.


Thursday 21 November 2013

Move Files and Folders to another Document Library or list in SharePoint 2010

Move Files and Folders to another Document Library  or list in SharePoint 2010









        private static void Main(string[] args)
        {
            SPSite siteColl = new SPSite("http://riponkundu/abc/");
            SPWeb site = siteColl.OpenWeb();
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite ElevatedsiteColl = new SPSite(siteColl.ID))
                {
                    using (SPWeb web = ElevatedsiteColl.OpenWeb(site.ID))
                    {
                        web.AllowUnsafeUpdates = true;
                        string listSrc = "My Documents";
                        string listDest = "My Documents Arc";
                        SPList sourceList = web.Lists.TryGetList(listSrc);
                        SPList targetList = web.Lists.TryGetList(listDest);
                        if (sourceList != null)
                        {
                            SPQuery query = new SPQuery();
                            query.Query = @"<Where><And><IsNotNull><FieldRef Name='ID' /></IsNotNull><Neq><FieldRef Name='ContentType' /><Value Type='Computed'>Folder</Value>
         </Neq></And></Where><QueryOptions><ViewAttributes Scope='RecursiveAll' /></QueryOptions>";
                            query.ViewAttributes = "Scope='RecursiveAll'";
                            SPListItemCollection coll = sourceList.GetItems(query);
                            for (int i = 0; i < coll.Count; i++)
                            {
                                SPListItem sourceItem = sourceList.GetItemById(Convert.ToInt32(coll[i]["ID"]));
                               
                                string modTime = sourceItem["Modified"].ToString();
                                string folderName = sourceItem.Web.GetFile(sourceItem.Url).ParentFolder.Name;//folder name
                                string folder = sourceItem.Web.GetFile(sourceItem.Url).ParentFolder.ServerRelativeUrl;//folder URL
                                SPFolder sourceFolder = sourceItem.Folder;
                                string targetPath = targetList.RootFolder.ServerRelativeUrl + "/" + folderName;
                                SPFolder targetFolder = web.GetFolder(targetPath);
                                SPListItem targetItem = targetFolder.Item;

                                if (Convert.ToDateTime(modTime) <= System.DateTime.Now.AddHours(-4))
                                {
                                    #region check for check out item and make in CheckedIn
                                    if (sourceItem.FileSystemObjectType == SPFileSystemObjectType.File)
                                    {
                                        SPFile sourceFile = sourceItem.File;
                                        if (sourceFile.CheckOutStatus != SPFile.SPCheckOutStatus.None)
                                        {
                                            Console.WriteLine(sourceItem.Name);
                                            sourceFile.UndoCheckOut();
                                        }
                                    }
                                    #endregion
                                    if (web.GetFolder(targetPath).Exists==false)
                                    {
                                        SPFolderCollection targetFolderColl = web.Folders;
                                        targetFolderColl.Add(web.Url+"/"+listDest+"/"+folderName);
                                       
                                    }
                                   
                                    SPFolder oFolder = web.GetFolder(listDest);
                                    SPFile file = web.Folders[listSrc].SubFolders[folderName].Files[sourceItem.Name.ToString()];
                                    file.MoveTo(oFolder.Url + "/"+ folderName +"/" + file.Name, true);
                                }
                            }
                          
                        }
                        web.AllowUnsafeUpdates = false;
                    }
                }
            });
        }

Sunday 17 November 2013

Update SharePoint 2010 Farm Credentials Using PowerShell

Update SharePoint 2010 Farm Credentials Using PowerShell



#Input the Managed Account
#If there is only one managed account, the following line could be written as:
#$inputManagedAcct = Get-SPManagedAccount

$inputManagedAcct = Read-Host "Enter managed account as Domain\User" 
#Input the desired new password 
$inputPasswd = Read-Host "Enter new password for managed account" –AsSecureString 
#Change the password for the managed account to the new value 
Set-SPManagedAccount -Identity $inputManagedAcct -NewPassword $inputPasswd



------------------------------------------------------------------------------------------------------------------------------------------------------------       Update after AD Reset    ----------------------------------------------------------------

#Input the Managed Account
#If there is only one managed account, the following line could be written as:
#$inputManagedAcct = Get-SPManagedAccount

$inputManagedAcct = Read-Host "Enter managed account as Domain\User:" 
#Input the Managed Account 
$inputPasswd = Read-Host "Enter password from Active Directory for managed account:" –AsSecureString 
#Change the password in SharePoint for the managed account to the new value 
Set-SPManagedAccount -Identity $inputManagedAcct -ExistingPassword $inputPasswd –UseExistingPassword $true 

SharePoint Search crawling got stuck at stopping or crawlling!!

PowerShell script to set crawl status as idle


You may face issue sometimes in crawl component configuration of SharePoint 2010/2013 Search. If you change any configuration of crawl, you must run full crawl once, or else it will throw error in backup operation. If a crawler is in running state, it will not allow you to change scope or sites url. To set the crawl status of a search service write search service name in below script

Get-SPEnterpriseSearchCrawlContentSource -SearchApplication "Search Service Application" | ForEach-Object {
     if ($_.CrawlStatus -ne "Idle")
     {
         Write-Host "Stopping currently running crawl for content source $($_.Name)..."
         $_.StopCrawl()
        
         do { Start-Sleep -Seconds 1 }
         while ($_.CrawlStatus -ne "Idle")
     }
}









Powershell to restart timer service in Multitier SharePoint Farm

The SharePoint Timer service



As a single unified logical entity, a SharePoint farm requires a mechanism to run tasks necessary to provide its services. These tasks include updating components of the farm such as servers and services, and updating data and configuration in farm databases. To run these tasks, SharePoint provides its own scheduled tasks management service, manifested as Timer Service instances installed on every SharePoint server in the farm. If the Timer Service or any of its instances on servers begins to malfunction, it won't take long for problems to begin appearing across the farm. For all its importance, though, the Timer Service is often misunderstood. In this blog post we'll explore the basic elements and startup process of the SharePoint Timer Service. In the future and as time permits, we'll further explore the Timer Job system and many of the specific Timer Jobs which run in a farm.


Start the timer service:
  1. Verify that the user account that is performing this procedure is a member of the Administrators group on the local computer.
  2. Open a Command Prompt window, type the following command at the command prompt, and then press ENTER:
    net start sptimerv4
  3. If the service does not start, ensure that the service identity account is configured correctly by using the "Verify the service account" procedure later in this article.

Verify the service account:

  1. Verify that the user account that is performing this procedure is a member of the Administrators group on the local computer.
  2. Click Start, click Administrative Tools, and then click Services.
  3. Right-click Windows SharePoint Services Timer V4, and then click Properties.
  4. On the Log On tab, confirm that the account being used is a domain user account and is a member of the following:
    • dbcreator fixed SQL Server server role
    • securityadmin fixed SQL Server server role
    • db_owner fixed database role for all databases in the server farm
  5. If the account has sufficient permissions, confirm the password by typing the password for the account, retyping the password in the Confirm password box, and then clicking OK.
  6. Start the service by right-clicking the service name in the Services console, and then clicking Start.

Set Timer job status Online in Multiserver Farm:

$farm  = Get-SPFarm
$disabledTimers = $farm.TimerService.Instances | where {$_.Status -ne "Online"}
if ($disabledTimers -ne $null)
{
    foreach ($timer in $disabledTimers)
    {
        Write-Host "Timer service instance on server " $timer.Server.Name " is not Online. Current status:" $timer.Status
        Write-Host "Attempting to set the status of the service instance to online"
        $timer.Status = [Microsoft.SharePoint.Administration.SPObjectStatus]::Online
        $timer.Update()
    }
}
else
{
    Write-Host "All Timer Service Instances in the farm are online! No problems found"

}


Timer job restart in Multiserver farm:

Use powershell script to restart timer services of all servers in a farm. Run below script in any server of a farm.

$farm = Get-SPFarm

$farm.TimerService.Instances | foreach {$_.Stop();$_.Start();}



You can get this job done in more interactive way by running below bunch of lines in SharePoint Management Shell


[array]$servers= Get-SPServer | ? {$_.Role -eq "Application"}
foreach ($server in $servers)
{
    Write-Host "Restarting Timer Service on $server"
    $Service = Get-WmiObject -Computer $server.name Win32_Service -Filter "Name='SPTimerV4'"
    if ($Service -ne $null)
    {
        $Service.InvokeMethod('StopService',$null)
        Start-Sleep -s 8
        $service.InvokeMethod('StartService',$null)
        Start-Sleep -s 5
        Write-Host -ForegroundColor Green "Timer Job successfully restarted on $server"
    }
    else
    { 
        Write-Host -ForegroundColor Red "Could not find SharePoint Timer Service on $server"
    }
}


SharePoint 2010 Configuration Wizard/ PSConfig getting failed!!

Run PSCONFIG after Installing SharePoint 2010 Patches



Since SharePoint Foundation 2010, patching SharePoint is a two-step process. The updated binaries are first installed and then PSCONFIG must be completed to update the SharePoint databases. 

Without completing PSCONFIG, you might experience unexpected SharePoint search failures and all backups may stop working on the affected server.

You can also run the following commands to determine if you need to complete the update process with PSCONFIG:
  • Launch an elevated (Run as Administrator) SharePoint 2010 Management shell from start, All Programs, Microsoft SharePoint 2010 Products, SharePoint 2010 Management Shell.
  • Once the shell opens, type the following command followed by enter:
    (get-spserver $env:computername).NeedsUpgrade



If the result of this command is True, then you need to complete the steps below. If the result is False then no further action is needed.
In order to update the SharePoint databases, you must manually run the PSconfig utility. To run the utility:
1. Open an Administrative command prompt.
2. Change directory to C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN
3. Run 
PSConfig.exe -cmd upgrade -inplace b2b -force -cmd applicationcontent -install -cmd installfeatures

Note: The Companyweb site will be inaccessible while the command is running. It is best to run the command after business hours. The amount of time the command takes to run will vary on the size of the database and the speed of the machine. On a reference machine with 8 logical processors, 32GB of RAM and a 2GB content database, the command took approximately 5 minutes to execute.
For additional information on SharePoint Foundation 2010 patching mechanism, please see the following TechNet article:

SharePoint 2010 Mobile view turn off using Powershell

Use Power shell script to turn off Mobile view of a SharePoint site


Run below mentioned script in your SharePoint server(enter your application URL in the script)


$webApp = Get-SPWebApplication http://<SharePoint webapplication URL>
$configMod = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
$configMod.Path = "configuration/system.web"
$configMod.Name = "browserCaps"
$configMod.Sequence = 0
$configMod.Type = 0
$configMod.Value = "<browserCaps> </browserCaps>"

$configMod1 = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
$configMod1.Path = "configuration/system.web/browserCaps"
$configMod1.Name = "result"
$configMod1.Sequence = 0
$configMod1.Type = 0
$configMod1.Value = "<result type=""System.Web.Mobile.MobileCapabilities, System.Web.Mobile, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a""/><filter>isMobileDevice=false</filter>"

$webApp.WebConfigModifications.Add($configMod)
$webApp.WebConfigModifications.Add($configMod1)
$webapp.Update()
$webapp.Parent.ApplyWebConfigModifications()

$webapp.WebConfigModifications.Clear()

Find missing webparts in a SharePoint 2010 Site Collection

Find missing webpart in a page:



stsadm -o enumallwebs -includewebparts > C:\temp\somelog.txt

Script to list all web parts in a site collection




function enumerateWebParts($Url) {
    $site = new-object Microsoft.SharePoint.SPSite $Url    foreach($web in $site.AllWebs) {
        if ([Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($web)) {
            $pWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
            $pages = $pWeb.PagesList
            foreach ($item in $pages.Items) {
                $fileUrl = $webUrl + “/” + $item.File.Url
                $manager = $item.file.GetLimitedWebPartManager([System.Web.UI.WebControls.Webparts.PersonalizationScope]::Shared);
                $wps = $manager.webparts
                $wps | select-object @{Expression={$pWeb.Url};Label=”Web URL”},@{Expression={$fileUrl};Label=”Page URL”}, DisplayTitle, IsVisible, @{Expression={$_.GetType().ToString()};Label=”Type”}
            }
        }
        else {
            $pages = $null
            $pages = $web.Lists["Site Pages"]            if ($pages) {                foreach ($item in $pages.Items) {
                    $fileUrl = $webUrl + “/” + $item.File.Url
                    $manager = $item.file.GetLimitedWebPartManager([System.Web.UI.WebControls.Webparts.PersonalizationScope]::Shared);
                    $wps = $manager.webparts
                    $wps | select-object @{Expression={$pWeb.Url};Label=”Web URL”},@{Expression={$fileUrl};Label=”Page URL”}, DisplayTitle, IsVisible, @{Expression={$_.GetType().ToString()};Label=”Type”}
                }
            }
            else {
            }
        }        Write-Host “… completed processing” $web
    }
}$row = enumerateWebParts(‘http://sp2010server:7070/’)
$row | Out-GridView



If the Integrated Script Editor (ISE) is not installed, execute the following script then go back to the script above and execute it.

Import-Module ServerManagerAdd-WindowsFeature PowerShell-ISE


Update InfoPath forms after content DB restore to different URL in SharePoint 2010

You may face issue in accessing InfoPath form after restoring a content database in new webapplication or sitecollection.




Assuming you have restore content DB of http://SP2010server:2323 to http://SP2010server:1666

First Test Content Database:

Test-SPContentDatabase –Name WSS_Content_1666 -WebApplication http://SP2010server:1666

Export Infopath form: 

You can use the Stsadm -o ExportIPFSAdminObjects command to collect and export InfoPath administrator deployed forms only

Import Infopath:

Import-SPInfoPathAdministrationFiles -path "E:\folder1\IPF.dat"

Update url of Infopath admin approved form:

Get-SPWebApplication http://SP2010server:1666 | Update-SPInfoPathAdminFileUrl –find "http://SP2010server:2323" –replace "http://SP2010server:1666"


Update url of  user input infopath forms:

Get-SPWebApplication http://SP2010server:1666 | Update-SPInfoPathUserFileUrl –find "https://myworld.sp.in" –replace "http://SP2010server:1666"

Get-SPWebApplication http://SP2010server:1666| Update-SPInfoPathUserFileUrl –find "http://SP2010server:2323 " –replace "http://iga-sp2k10-app:1666"




Run the following commands to force deactivating and activating the Forms Services feature:


stsadm -o deactivatefeature -filename IPFSSiteFeatures\feature.xml -force -url %SITE_COLLECTION_URL%

stsadm -o deactivatefeature -filename IPFSWebFeatures\feature.xml -force -url %SITE_COLLECTION_URL%

STSADM.EXE -o activatefeature -filename IPFSSiteFeatures\feature.xml -url %Sitecollection_URL% -force

STSADM.EXE -o activatefeature -filename IPFSWebFeatures\feature.xml -url %sitecollection_URL% -force

** NOTE: The “%Sitecollection_URL%” is a place holder that would be replaced with your site collection URL, such as: http://sharepoint/sites/YourSiteCollection

Configure and Flush Blob Cache in SharePoint 2010

Enable BLOB Cache using PowerShell?



Why not! Web.config file changes can be made with "SPWebConfigModification" class. Lets utilize that to make a web.config change to enable BLOB cache:

BLOB Cache Configuration has the following Parameters: 

  • location - Is the file system folder where SharePoint server stores cached files.Make sure you select the BLOB cache location on a drive with sufficient disk space!
  • path - Is a lists all file extensions that will be cached. File types are separated by vertical pipe character.
  • maxSize - In GB, disk space that the BLOB cache will occupy. If BLOBs exceeds this limit, SharePoint will delete older items in the cache to make room for newer items.
  • max-Age - In seconds. It tells How long Browser can cache these files without making request to the server. Use it with value: 1814400 (Three Weeks), if you get: HTTP 304 error!
  • enabled - Sets BLOB Cache ON or OFF. Make it "false" to disable BLOB Cache.

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Get the Web Application
$WebApp = Get-SPWebApplication "http://riponkundu.blogspot.in"

#Create a web.config modification
$WebconfigMod = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
$WebconfigMod.Path = "configuration/SharePoint/BlobCache"
$WebconfigMod.Name = "enabled"
$WebconfigMod.Sequence = 0
$WebconfigMod.Owner = "BlobCacheModification"
$WebconfigMod.Type = 1
$WebconfigMod.Value = "true"
    
#Apply the web.config change
$WebApp.WebConfigModifications.Add($WebconfigMod)
$WebApp.Update()
$WebApp.Parent.ApplyWebConfigModifications()


This will enable BLOB Cache. If you want to disable BLOB cache, just change the Parameter "enabled" to "false". Same method applies for additional parameters such as: Location, MaxSize, max-age etc.




How to Flush(Reset/Clear) BLOB cache in SharePoint 2010



Some times, You may notice your changes don’t appear in the site. All you have to do is: Flush the Cache! Here is the PowerShell to flush the BLOB cache (No GUI to do this!).


Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

$webApp = Get-SPWebApplication "http://riponkundu.blogspot.in"
[Microsoft.SharePoint.Publishing.PublishingCache]::FlushBlobCache($webApp)
Write-Host "BLOB Cache Flushed for:" $webApp



File Names Renaming- Powershell

It is easier to change multiple files names within a folder through Powershell.



You may want to rename thousands or millions of files within a folder with Folder name as prefix to them. Copy your folder URL and paste it at <URL of Folder>(we have also checked .jpg and .png files)

Friday 15 November 2013

Chrome Type for Web Parts in SharePoint 2010

Change Chrome type property of a webpart through Visual studio



 Chrome is the surrounding area around a web part that gives you a border, a title for the web part, and other aesthetics…if you want them. The problem is, often times when you are dealing with a public website, you do not want to show the chrome around a web part just because you have more control of your site’s look and feel when all of your visible elements are created from within the web part content.
There are a couple ways to disable chrome for a web part within SharePoint, each coming with a bit of a caveat. The first is to simply change the web part properties for a particular web part setting the chrome type to the desired case, which is ‘None’ in this case.

Chrome


We can also do the same thing in our web part definition (.webpart file), as shown below:
<?xml version="1.0" encoding="utf-8"?>
  <webParts>
    < webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
      < metaData>
          < type name="My.Namespace.and.type, $SharePoint.Project.AssemblyFullName$" />
          < importErrorMessage>$Resources:core,ImportErrorMessage;</importErrorMessage>
      < /metaData>
      < data>
        < properties>
            < property name="Title" type="string">My Web Part</property>
            < property name="Description" type="string">My Web Part’s description</property>
            < property name="ChromeType" type="chrometype">None</property>
        < /properties>
      < /data>
    < /webPart>
</webParts>


The problem with these two solutions is that you have to change every web part’s properties to set the chrome type, which is quite inefficient. The other way of doing this is a more global solution. Chrome type can be changed at the page layout level as well. Every web part zone has a PartChromeType property that can be set to one the defined values – in this case, we will choose ‘None’ for our publically facing website.

<WebPartPages:WebPartZone id="wpzMyZone" runat="server" title="My Zone" PartChromeType="None">

There is one big gotcha with all of this. Whenever a web part is placed on the page, the chrome type for that web part is written to the page metadata deep within the bowels of SharePoint. So changing the web part definition or changing the global layout will have no effect because it the web part chrome type has already been determined. So if you change the chrome type after a web part has been added to a page, you are left with two options: change it manually in the web part properties, or remove and re-add the web part to the page. 

Wednesday 2 October 2013

Remove alerts from all SharePoint Sites

Want to Remove alerts from all SharePoint web applications including each site collections and sub-sites?




*Do not run on Production Environment. Its should run on development and Testing Environment only.


Run below Powershell script:

foreach ($site in Get-SPSite -Limit All) 
{ 
  "Site Collection $site" 
  foreach ($web in $site.allwebs)
  {
     "  Web $web"
     $c = $web.alerts.count
     "    Deleting $c alerts"
     for ($i=$c-1;$i -ge 0; $i--) { $web.alerts.delete($i) }
  }
}

Wired of creating video page to support multiplatform! Try HTML5

Video for Everybody will give you the solution for this: 





Video for Everybody is simply a chunk of HTML code that embeds a video into a website using the HTML5 <video> element, falling back to Flash automatically without the use of JavaScript or browser-sniffing. It therefore works in RSS readers (no JavaScript), on the iPhone / iPad (don’t support Flash) and on many browsers and platforms.
Thanks to the rapid adoption of HTML5 video happening right now, Video for Everybody isn’t the only solution around. It is not a neatly packaged, fully-featured solution for those unfamiliar with HTML. VfE is for developers who either want something really simple they can quickly use on their blog or websites, or as a good starting point to develop their own custom solution. It does not use JavaScript. Because of this, it does not work on Android versions prior to 2.3 (Gingerbread). That is Google’s fault. If you don’t care about the reasons behind this you should just use a solution like MediaElement.js or VideoJS that do work on older versions of Android.


How It Works

If your browser supports it, HTML5 video is used. No Flash—no crash.



If HTML5 video is not supported, Adobe Flash is used.
You can host locally or embed any Flash player of your choice.



Finally, if all else fails, a placeholder image is shown and the user can download the video using the links provided. If the user doesn’t have Flash they are not prompted to install it. Users have enough problems with security already without random websites prompting them to install things—and it’s even more annoying for people who don’t want or cannot use Flash anyway. This is one aspect that makes VfE different than any other Flash video embedding method.





Final fallback image, you could use a different image that points to the download links

This is all done without JavaScript and requires two video encodes, one Ogg file, and one MP4 file. WebM can optionally be added. Instructions on how to convert your videos to these formats are provided further down this article.
It’s compatible with HTML 4, HTML5 (valid markup), XHTML 1 and additionally also works when served as application/xhtml+xml.

For a full browser compatibility list, see the Video for Everybody Test Page.



The Code

Here follows the full source code. It’s very large because it’s fully commented.
You can easily compact this down (one such example follows afterwards).
To save time you could use the Video for Everybody generator by Jonathan Neal to generate the code snippet according to your options.

Do not miss the important notes below or you will be kicking yourself after wasting hours trying to get it to work.
<!-- first try HTML5 playback: if serving as XML, expand `controls` to `controls="controls"` and autoplay likewise -->
<!-- warning: playback does not work on iOS3 if you include the poster attribute! fixed in iOS4.0 -->
<video width="640" height="360" controls>
 <!-- MP4 must be first for iPad! -->
 <source src="__VIDEO__.MP4" type="video/mp4" /><!-- Safari / iOS video    -->
 <source src="__VIDEO__.OGV" type="video/ogg" /><!-- Firefox / Opera / Chrome10 -->
 <!-- fallback to Flash: -->
 <object width="640" height="360" type="application/x-shockwave-flash" data="__FLASH__.SWF">
  <!-- Firefox uses the `data` attribute above, IE/Safari uses the param below -->
  <param name="movie" value="__FLASH__.SWF" />
  <param name="flashvars" value="controlbar=over&amp;image=__POSTER__.JPG&amp;file=__VIDEO__.MP4" />
  <!-- fallback image. note the title field below, put the title of the video there -->
  <img src="__VIDEO__.JPG" width="640" height="360" alt="__TITLE__"
       title="No video playback capabilities, please download the video below" />
 </object>
</video>
<!-- you *must* offer a download link as they may be able to play the file locally. customise this bit all you want -->
<p> <strong>Download Video:</strong>
 Closed Format: <a href="__VIDEO__.MP4">"MP4"</a>
 Open Format: <a href="__VIDEO__.OGV">"Ogg"</a>
</p>
(If you would like your video to automatically start playing, check out the sample code on the test page.)

Here’s a compacted version as an example:
<video width="640" height="360" controls>
 <source src="__VIDEO__.MP4"  type="video/mp4" />
 <source src="__VIDEO__.OGV"  type="video/ogg" />
 <object width="640" height="360" type="application/x-shockwave-flash" data="__FLASH__.SWF">
  <param name="movie" value="__FLASH__.SWF" />
  <param name="flashvars" value="controlbar=over&amp;image=__POSTER__.JPG&amp;file=__VIDEO__.MP4" />
  <img src="__VIDEO__.JPG" width="640" height="360" alt="__TITLE__"
       title="No video playback capabilities, please download the video below" />
 </object>
</video>
<p> <strong>Download Video:</strong>
 Closed Format: <a href="__VIDEO__.MP4">"MP4"</a>
 Open Format: <a href="__VIDEO__.OGV">"Ogg"</a>
</p>
And one that auto plays: (notice the changes “autoplay” and “autostart=true”)
<video width="640" height="360" controls autoplay>
 <source src="__VIDEO__.MP4"  type="video/mp4" />
 <source src="__VIDEO__.OGV"  type="video/ogg" />
 <object width="640" height="360" type="application/x-shockwave-flash" data="__FLASH__.SWF">
  <param name="movie" value="__FLASH__.SWF" />
  <param name="flashvars" value="autostart=true&amp;controlbar=over&amp;image=__POSTER__.JPG&amp;file=__VIDEO__.MP4" />
  <img src="__VIDEO__.JPG" width="640" height="360" alt="__TITLE__"
       title="No video playback capabilities, please download the video below" />
 </object>
</video>
<p> <strong>Download Video:</strong>
 Closed Format: <a href="__VIDEO__.MP4">"MP4"</a>
 Open Format: <a href="__VIDEO__.OGV">"Ogg"</a>
</p>
It’s advised you subscribe to the RSS to be kept informed of new releases in case you get caught out by new bugs introduced by vendors *cough*Apple*cough*. The version isn’t <1 for no reason.

IMPORTANT Notes

  1. Ensure your server is using the correct mime-types. Firefox will not play the Ogg video if the mime-type is wrong. Place these lines in your .htaccess file to send the correct mime-types to browsers
    AddType video/ogg  .ogv
    AddType video/mp4  .mp4
    AddType video/webm .webm
  2. Replace __VIDEO__.MP4 with the path to your video encoded to MP4 (a warning on using H.264) and
    replace __VIDEO__.OGV with the path to your video encoded to Ogg.
    Optionally you could also include a WebM video.
  3. Replace __POSTER__.JPG with the path to an image you want to act as a title screen to the video, it will be shown before the video plays, and as a representative image when the video is unable to play (Also replace “__TITLE__” for the poster image’s alt text). Not all browsers support the poster attribute, it’s advisable to encode the poster image into the first frame of your video.
    DO NOT INCLUDE THE poster ATTRIBUTE (<video poster="…">) FOR iOS 3.x SUPPORT. There is a major bug with iOS 3 that means that playback will not work on any HTML5 video tag that uses both the poster attribute and <source> elements. This was fixed in iOS 4.0, but of course for now there will still be a large number of OS 3 users. This bug does not affect use of the poster image in the flashvars parameter, which you should retain
  4. Replace __FLASH__.SWF with the path to the Flash video player you are using. I use JW Player(download and place ‘player.swf’ in the right place), but this could be any Flash resource including YouTube. Sample code for using YouTube can be seen on the Video for Everybody YouTube Test Page
  5. Safari buffers the video automatically even if autobuffer is absent. This has been fixed in WebKit nightlies with a change to the HTML5 spec; the “preload="none"” attribute on the video element prevents autobuffering. A current bug in WebKit causes Safari to perpetually display “loading” until the play button is clicked
  6. The iPhone will not autoplay. This is done to save bandwidth which may cost some users, or be limited.
    It is not a bug, it’s a feature
  7. HTML5 video on Android is badly broken. Resolution support varies from one handset to the next (often just 480×360), the fallback image usually doesn’t show and the code requires special adjustments. The Android emulator is completely useless as it doesn’t represent any real hardware and does not play HTML5 video. THERE IS NO WAY TO TEST ON ANDROID WITHOUT A PHYSICAL PHONE. BLAME GOOGLE.
    Android 2.3 (Gingerbread) now finally supports the controls attribute, so that VfE can work, but this still leaves all previous Android versions in the lurch. Use MediaElement.js or VideoJS for better Android support.
  8. Some web hosts, in trying to save bandwidth, gzip everything by default—including video files! In Firefox and Opera, seeking will not be possible or the video may not play at all if a video file is gzipped. If this is occurring to you please check your server / hosts and disable the gzipping of Ogg and other media files. You can switch off gzipping for video files in your .htaccess file by adding this line:
    SetEnvIfNoCase Request_URI \.(og[gv]|mp4|m4v|webm)$ no-gzip dont-vary
    With thanks to Bas van Bergen for this tip
  9. There are some instances where people will simply not be able to view the video inside the web-page (e.g. Opera Mobile / Mini). It is absolutely essential that you provide download links outside of the video to ensure your message gets through
  10. A current bug in Firefox means that when JavaScript is disabled (NoScript for example) the video controls do not display. For now, right-click on the video for the controls, use autoplay on your videos or rely on users allowing your site in NoScript
  11. The Eolas ‘Click to Activate’ issue affects Flash in Internet Explorer 6 / 7 as the ActiveX controls are not inserted using JavaScript—however Microsoft removed ‘Click to Activate’ in a later update patch. This issue will not affect users who have run Windows Update.
    Please also note that Windows XP originally shipped with Flash v6, and H.264 playback in Flash requires v9 or 10. Depending on what Flash video player you use, this may cause problems if you intend to support users with out of date Flash versions
  12. A parsing bug in Camino 2.0 / Firefox 3.0 means that the image element inside the video element will ‘leak’ outside of the video element. This is not visible however unless some kind of background image or colour is applied to that image element. You can stop this by either wrapping the video element in another element or modifying the code from “<source … />” to “<source …></source>”. This works, but will not validate as HTML5

Adding Custom Controls

Since VfE doesn’t come with any JavaScript the HTML5 video will use whatever native interface the browser provides. This is in the best interest of the user because it provides an interface best tailored to that device. For example, the iPhone always plays video fullscreen so that the edges of the video are not cut off in the browser and the user does not have to pan around to get it all in view. The iPad provides finger-friendly sized controls.














Different native video controls in Opera 10.5 and Google Chrome

Designers however don’t like the inconsistency and would like a unified set of controls. Both MediaElement.js and VideoJS use VfE and custom controls you can style how you please with CSS.

Encoding the Videos

Full instructions are beyond the scope of this article, please refer to Mark Pilgrim’s Video on the Web article for an excellent introduction to video formats and encoding instructions. As WebM is quite new, here is a quick guide to encoding WebM video.
  • There is no restriction on the resolution of the Ogg video
  • The iPhone can play MOV and MPEG4 videos with a maximum size of 640×480 and only allows the Base Profile for H.264 (See Apple’s own instructions for the specifics). If your desired video is bigger than that, please read the instructions below for how to adjust the code to use hi-res videos whilst keeping iPhone compatibility
  • The iPad can play H.264 up to 720p, 30 FPS
  • Firefox will only play Ogg (WebM is also supported in Firefox 4), and it will not degrade to Flash if there is no Firefox-compatible video file
  • For best results I recommend including the poster image as the first frame when you encode the video

Using HD Video

If you would like to use a larger video than 640×480, you can use a QuickTime reference movie to auto-select between an iPhone compatible version and the full-size video. In QuickTime Pro use the ‘File » Export for Web…’ option to output a reference movie (you can also use Apple’s MakeRefMovie tool for finer control). You’ll have three files along these lines: “video.mov”, “video-desktop.mp4” (or m4v) and “video-iphone.mp4”. Now replace the two source elements in the code with these three: (substituting the right file paths)
<source src="video.mov" type="video/mp4"></source><source src="video-desktop.mp4" type="video/mp4"></source><source src="video.ogv" type="video/ogg"></source>
What happens here is that the browser will play the QuickTime reference movie (Safari / iPhone / iPad) which will auto-select between the desktop and iPhone versions of the video automatically. If the MOV format isn’t supported by the browser (Chrome for example), we point to the same MPEG4 video that the QuickTime reference movie uses.

A Warning About H.264

I made Video for Everybody because since I don’t have Flash installed I wanted to create a way websites could provide me access to their videos (currently needlessly trapped inside Flash) without having to lose viewers from older browsers. VfE is not a tool I would use myself (other videos on this site are HTML5/Ogg only) because of the threat that H.264 represents to freedom on the web. Websites that are already serving H.264 video to users using Flash have already made the conscious decision to buy into H.264. I am not making that decision for you with Video for Everybody.
Just be aware that if you decide to use H.264 video for commercial use then you will need to purchase a licence from the MPEG-LA. Be warned that ‘commercial use’ may also include the scenario where your website has advertisements, even though your use of video is unrelated to those adverts. If you are making any any money in any way from a page that also includes an H.264 video, then you should contact the MPEG-LA for help on licencing.
On the 27th of August 2010, the MPEG-LA announced (arguably in response to growing WebM support) that the terms of “free use” of H.264 Internet broadcast would not change in 2016. This does not change a thing.
"This is similar to Nikon announcing that they will not charge you if you put your pictures up on Flickr, or HP promising that they will never charge you additionally if you photocopy something that you printed on a LaserJet."
-Mike Shaver

Using WebM Video

On the 19th of May 2010 Google released the VP8 codec as open-source and royalty free with the full intent to drive broad adoption via industry backing and switching YouTube over to the new format in the long term. “WebM” is a rebranded Matroska container utilising VP8 video and
OggVorbis audio.
This represents major competition to H.264—Mozilla, Google and Opera have already added support into special builds of their browsers and even Microsoft have about-faced on their H.264-only policy and said that IE9 will support WebM—but only if the codec has been installed by the user. Obviously absent from any support is Apple, and this means that unfortunately codec-fragmentation will continue into the foreseeable future so that you will still need to provide more than one video encode.
Adding a WebM video to Video for Everybody is easy, just add it to the source list! It has to go below the MP4 video due to an iPad bug that ignores anything but the first source element, and ideally above the Ogg source so that browsers that play both Ogg and WebM choose the WebM video first. Here is an example source stack:
<source src="video.mp4" type="video/mp4" /><source src="video.webm" type="video/webm" /><source src="video.ogv" type="video/ogg" />
Note the new mime type, which you will have to add to your server.
As WebM is quite new, here is a quick guide to encoding WebM video.
On January 11th 2011, Google announced that it would be removing H.264 support from Chrome. It is clear that Google’s long-term solution is to transition YouTube to HTML5/WebM. With the release of Firefox 4, a large percentage of browsers will support WebM, and others through the use of installed codecs (Safari and IE9). Only iOS is completely without WebM support at this time.
Please note that you do not have to include WebM video in your HTML5 video tags as both Chrome, Firefox and Opera still support Ogg. WebM will provide you higher quality, and likely wider compatibility in the very near future, but right now it is an optional extra.
If you’ve modified Video for Everybody to do something else, or have created an HTML5 video related project, please let me know and if it upholds the same principles as Video for Everybody, I’ll list it here.
(I will not list projects that cannot play the video in an RSS reader. Using JavaScript to insert <video> defeats the entire purpose.)
MediaElement.js
Based on Video for Everybody but uses a custom Flash or Silverlight player that mimics the native HTML5 API so that interacting with the video from JavaScript is the same regardless of browser. Truly a great piece of work. Video controls are doing using HTML / CSS for cross-browser consistency. MediaElement.js also includes support for sub-titling and has plugins for popular blogging engines. Its only downside is that it requires jQuery (where VideoJS below is library-agnostic).
video.js
Based on Video for Everybody but adds custom video controls made of HTML that you can style anyway you please with a bit of CSS. VideoJS uses JavaScript to patch up browser differences and bugs, so offers much better support than Video for Everybody.
External Video for Everybody
A WordPress plugin that provides a shortcode to insert video using Video for Everybody. The author has also provided an excellent bash script to automate the process of encoding the video files.

Acknowledgements