<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Giuseppe Guerrasio</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/giuseppeguerrasio/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/giuseppeguerrasio/feed.xml</link>
    <description>Building the next web platform</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:08:08 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Live Streaming with Azure Media Services - Part 1</title>
      <link>https://docs.microsoft.com/archive/blogs/giuseppeguerrasio/live-streaming-with-azure-media-services-part-1</link>
      <pubDate>Wed, 11 Apr 2018 15:25:52 GMT</pubDate>
      <dc:creator><![CDATA[Giuseppe Guerrasio]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuseppeguerrasio/?p=1195</guid>
      <description><![CDATA[One of the most frequent question that I receive from the discussion with customer and partner that...]]></description>
      <content:encoded><![CDATA[<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> One of the most frequent question that I receive from the discussion with customer and partner that are starting to adopt cloud services for media delivery, is about live streaming with Azure Media Service (AMS). Typical questions are about high availability ,  how to maintain the publishing URL for long running live streming, also in the case of encoder restart and other.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">Before to start to respond , the first step is starting from a description of the AMS <span> </span>architecture, in order to understand more in depth how the live streaming works in this Platform, and after that , map the concepts that you need to implement on the platform architecture. In this part we are describing the AMS v2 API's  that currently are in GA.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">AMS is very flexible and useful to deliver live premium content. Today, we have to leverage a large number of formats and content protection technology, to deliver premium content to a large number of different device that are used in the consumer and enterprise space, and AMS offers with Dynamic Encryption and Dynamic Streaming, offers a very efficient way to deliver multiple format and content protection system, starting from a single video source. </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">You can stream using MPEG-DASH, HLSv3, HLSv4 , Smooth Streaming and leverage the most relevant DRM systems PlayReady, Widevine and FairPlay,<span>  </span>that can permit to cover the most used endpoints (PC, Mac, Mobile Phone Tablet, Connected Tv, etc) in the market today.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"></span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">You can leverage in input two main protocols in order to push the video content to the platform, like RTMP , fmp4 over HTTP (smooth streaming) , and you can use two different workflow to send the content and stream it:</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">- pass-throug workflow<span>  </span>where you push all the quality levels that you would like to leverage in your streaming with a multibitrate input . With this workflow you can run 24h streaming.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">- live encoder workflow where you push a single bitrate and leverage a live encoder in AMS, in order to create the multiple bitrate levels to stream the content at different quality level to the client . This workflow in the current version is suggested for live streaming with a duration no more of 8 hours<span> .</span></span></span>

<img src="https://msdnshared.blob.core.windows.net/images/postliveams1p1.jpg" />

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">This platform can be managed leveraging a specific set of REST API that you can use to create and manage the live channel services and integrate it with your workflow and application. You can also leverage the Azure Portal as front end,<span>  </span>and the AMS Explorer tool that show you a sample of how to use the API from C#.</span></span>

<span style="font-family: Calibri"><span lang="EN-US"><span style="color: #000000">In addition to the streaming services, AMS offers also a preview monitoring feature and can ingest and record the content to offers it ondemand during the live streaming or after the live event, it has also a set of API with<span>  </span>a JavaScrip application to clip and cut the content to repurpose it (Azure Media Clipper </span></span><a href="https://docs.microsoft.com/en-us/azure/media-services/media-services-azure-media-clipper-overview"><span lang="EN-US">https://docs.microsoft.com/en-us/azure/media-services/media-services-azure-media-clipper-overview</span></a><span lang="EN-US"><span><span style="color: #000000">  </span></span></span><a href="https://azuremediaclipper.azurewebsites.net/"><span lang="EN-US">https://azuremediaclipper.azurewebsites.net/</span></a><span lang="EN-US"><span style="color: #000000">), a customizable player (Azure Media Player </span></span><a href="http://ampdemo.azureedge.net/azuremediaplayer.html"><span lang="EN-US">http://ampdemo.azureedge.net/azuremediaplayer.html</span></a><span lang="EN-US"><span style="color: #000000"> ) that you can leverage for several web client. </span></span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">After a brief overview of the service, now we can start to go more in depth in the architectural detail that the service leverage.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">The main component without the DRM part that we will analyze in a second step are:</span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Channel</span></span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Program</span></span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Asset</span></span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Access Policy</span></span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Locator</span></span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Streaming Endpoint</span></span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">The channel is the entry point of the video content. It takes in input the video signal that we want stream and accepts it with some types of input. As mentioned it can work as passthrough or can leverage a live encoder . With pass-through<span>  </span>you can send multiple stream with different bitrate/resolutions in order to have different quality levels in your streaming, to permit to the client consumer endpoint to leverage adaptive streaming and select the best quality based on the network conditions.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">Using pass-through <span> </span>or live encoder you can leverage RTMP and fmp4 and you have 2 RTMP input (primary and secondary) to permit to implement an high available streaming, sending two set of streams with the same timecode aligned. <span> </span>We will talk more about how to implement this in a next part of the article. </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">The channel offers also an endpoint to monitor the streaming that the channel receive and prepare for streaming. Currently the preview is delivered with Smooth Streaming only and it is required a player compatible with Smooth Streaming.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"></span></span>

<img class="aligncenter" src="https://msdnshared.blob.core.windows.net/images/postliveams1p2.png" />

&nbsp;

<span style="font-family: Calibri"><span lang="EN-US"><span style="color: #000000">At this link </span></span><a href="https://docs.microsoft.com/en-us/azure/media-services/media-services-recommended-encoders"><span lang="EN-US">https://docs.microsoft.com/en-us/azure/media-services/media-services-recommended-encoders</span></a><span lang="EN-US"><span style="color: #000000"> you can find a list of recommended encoders that you can leverage to push content to Azure Media Services channel.</span></span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">You have to select at the channel creation, if you would like to use pass-through or live encoder.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">You can create the Channel using AMS REST API (https://rest.media.azure.net), Azure Portal , MS Explorer sample application or one of the SDK for AMS . </span></span>

<span style="font-family: Calibri"><span lang="EN-US"><span style="color: #000000">For delivering a test to create a channel leveraging REST API , you can also use Postman and the configurations required for this test are available at this link </span></span><a href="https://docs.microsoft.com/en-us/azure/media-services/media-rest-apis-with-postman"><span lang="EN-US">https://docs.microsoft.com/en-us/azure/media-services/media-rest-apis-with-postman</span></a><span lang="EN-US"><span style="color: #000000"> </span></span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">A channel can receive different type of command:</span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Start : to start the channel and put it in Running state, a state ready to receive the video stream</span></span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Stop: to stop the channel and deallocate the resources connected to the live channel without destroy the channel configuration</span></span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Reset: to reset the input channel in the case that you need to restart a new streaming in input</span></span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">Possible state values include:</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">- Stopped. This is the initial state of the Channel after its creation. In this state, the Channel properties can be updated but streaming is not allowed.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">- Starting. Channel is being started. No updates or streaming is allowed during this state. If an error occurs, the Channel returns to the Stopped state.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">- Running. The Channel is capable of processing live streams.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">- Stopping. The channel is being stopped. No updates or streaming is allowed during this state.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">- Deleting. The Channel is being deleted. No updates or streaming is allowed during this state.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">In order to reset , stop or delete a channel is required that it isn’t connected to a running program, we will describe more about program entity below in this article.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">Be aware that there is a billing impact for live channel that you should remember that leaving a live<span>  </span>channel in the "Running" state will incur billing charges. It is recommended that you immediately stop your running channels after your live streaming event is complete to avoid extra hourly charges.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">A Channel can be created using a POST HTTP request, specifying property values and the Authentication token that you have to get from AAD Login for a user or service principal that has the permissions to manage live channel in the AMS instance in the subscription that you are using. </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>

<span lang="EN-US">POST https://&lt;accountname&gt;.restv2.&lt;location&gt;.media.azure.net/api/Channels HTTP/1.1<span>  </span></span>

<span lang="EN-US">DataServiceVersion: 3.0;NetFx<span>  </span></span>

<span lang="EN-US">MaxDataServiceVersion: 3.0;NetFx<span>  </span></span>

<span lang="EN-US">Accept: application/json;odata=minimalmetadata<span>  </span></span>

<span lang="EN-US">Accept-Charset: UTF-8<span>  </span></span>

<span lang="EN-US">x-ms-version: 2.11<span>  </span></span>

<span lang="EN-US">Content-Type: application/json;odata=minimalmetadata<span>  </span></span>

<span lang="EN-US">Host: &lt;host URI&gt;<span>  </span></span>

<span lang="EN-US">User-Agent: Microsoft ADO.NET Data Services<span>  </span></span>

<span lang="EN-US">Authorization: Bearer &lt;token value&gt;<span>  </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>

<span lang="EN-US">{<span>  </span></span>

<span lang="EN-US">"Id":null,<span>  </span></span>

<span lang="EN-US">"Name":"testchannel001",<span>  </span></span>

<span lang="EN-US">"Description":"",<span>  </span></span>

<span lang="EN-US">"Created":"0001-01-01T00:00:00",<span>  </span></span>

<span lang="EN-US">"LastModified":"0001-01-01T00:00:00",<span>  </span></span>

<span lang="EN-US">"State":null,<span>  </span></span>

<span lang="EN-US">"Input":<span>  </span></span>

<span lang="EN-US"><span>   </span>{<span>  </span></span>

<span lang="EN-US"><span>   </span>"KeyFrameInterval":null,<span>  </span></span>

<span lang="EN-US"><span>   </span>"StreamingProtocol":"FragmentedMP4",<span>  </span></span>

<span lang="EN-US"><span>   </span>"AccessControl":<span>  </span></span>

<span lang="EN-US"><span>      </span>{<span>  </span></span>

<span lang="EN-US"><span>         </span>"IP":<span>  </span></span>

<span lang="EN-US"><span>         </span>{<span>  </span></span>

<span lang="EN-US"><span>            </span>"Allow":[{"Name":"testName1","Address":"1.1.1.1","SubnetPrefixLength":24}]<span>  </span></span>

<span lang="EN-US"><span>         </span>}<span>  </span></span>

<span lang="EN-US"><span>      </span>},<span>  </span></span>

<span lang="EN-US"><span>   </span>"Endpoints":[]<span>  </span></span>

<span lang="EN-US"><span>   </span>},<span>  </span></span>

<span lang="EN-US">"Preview":<span>  </span></span>

<span lang="EN-US"><span>   </span>{<span>  </span></span>

<span lang="EN-US"><span>   </span>"AccessControl":<span>  </span></span>

<span lang="EN-US"><span>      </span>{<span>  </span></span>

<span lang="EN-US"><span>         </span>"IP":<span>  </span></span>

<span lang="EN-US"><span>         </span>{<span>  </span></span>

<span lang="EN-US"><span>            </span>"Allow":[{"Name":"testName1","Address":"1.1.1.1","SubnetPrefixLength":24}]<span>  </span></span>

<span lang="EN-US"><span>         </span>}<span>  </span></span>

<span lang="EN-US"><span>      </span>},<span>  </span></span>

<span lang="EN-US"><span>      </span>"Endpoints":[]<span>  </span></span>

<span lang="EN-US"><span>   </span>},<span>  </span></span>

<span lang="EN-US">"Output":<span>  </span></span>

<span lang="EN-US"><span>   </span>{<span>  </span></span>

<span lang="EN-US"><span>   </span>"Hls":<span>  </span></span>

<span lang="EN-US"><span>      </span>{<span>  </span></span>

<span lang="EN-US"><span>         </span>"FragmentsPerSegment":1<span>  </span></span>

<span lang="EN-US"><span>      </span>}<span>  </span></span>

<span lang="EN-US"><span>   </span>},<span>  </span></span>

<span lang="EN-US">"CrossSiteAccessPolicies":<span>  </span></span>

<span lang="EN-US"><span>   </span>{<span>  </span></span>

<span lang="EN-US"><span>   </span><span>   </span>"ClientAccessPolicy":null,<span>  </span></span>

<span lang="EN-US"><span>      </span>"CrossDomainPolicy":null<span>  </span></span>

<span lang="EN-US"><span>   </span>}<span>  </span></span>

<span lang="EN-US">}<span>  </span></span>

&nbsp;

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span><span lang="EN-US"><span style="color: #000000;font-family: Calibri">As you can see from the body of the previous request , you have to specify the Input Protocol that you would like to use, the IP addresses that you would like to authorize to push the content to the input for the channel and for the preview, the Key Frame interval for the video content fragment (optional) and the number of HLS fragments that the Live Streaming have to use to create an HLS segment, Cross site Settings Policy used to manage cross domain request from client.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">if the request is successful you will receive HTTP 202 accepted and the request will be processed asynchronously, and you can check the status of the channel to see when it move from starting to running.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span><span lang="EN-US"><span style="color: #000000;font-family: Calibri">To start the Channel after the creation complete you can send a specific POST like below:</span></span>

&nbsp;

<span lang="EN-US">POST https://&lt;accountname&gt;.restv2.&lt;location&gt;.media.azure.net/api/Channels('nb:chid:UUID:2c30f424-ab90-40c6-ba41-52a993e9d393')/Start HTTP/1.1<span>  </span></span>

<span lang="EN-US">DataServiceVersion: 3.0;NetFx<span>  </span></span>

<span lang="EN-US">MaxDataServiceVersion: 3.0;NetFx<span>  </span></span>

<span lang="EN-US">Accept: application/json;odata=minimalmetadata<span>  </span></span>

<span lang="EN-US">Accept-Charset: UTF-8<span>  </span></span>

<span lang="EN-US">x-ms-version: 2.11<span>  </span></span>

<span lang="EN-US">Content-Type: application/json;odata=minimalmetadata<span>  </span></span>

<span lang="EN-US">Host: &lt;host URI&gt;<span>  </span></span>

<span lang="EN-US">User-Agent: Microsoft ADO.NET Data Services<span>  </span></span>

<span lang="EN-US">Authorization: Bearer &lt;token value&gt;<span>  </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">Also in this case, if the request is successful you will receive HTTP 202 accepted and the request will be processed asynchronously and you can check the status of the channel to see when it move from starting to running.</span></span>

<span lang="EN-US">POST https://&lt;accountname&gt;.restv2.&lt;location&gt;.media.azure.net/api/Channels('nb:chid:UUID:2c30f424-ab90-40c6-ba41-52a993e9d393')/State  HTTP/1.1<span>  </span></span>

<span lang="EN-US">DataServiceVersion: 3.0;NetFx<span>  </span></span>

<span lang="EN-US">MaxDataServiceVersion: 3.0;NetFx<span>  </span></span>

<span lang="EN-US">Accept: application/json;odata=minimalmetadata<span>  </span></span>

<span lang="EN-US">Accept-Charset: UTF-8<span>  </span></span>

<span lang="EN-US">x-ms-version: 2.11<span>  </span></span>

<span lang="EN-US">Content-Type: application/json;odata=minimalmetadata<span>  </span></span>

<span lang="EN-US">Host: &lt;host URI&gt;<span>  </span></span>

<span lang="EN-US">User-Agent: Microsoft ADO.NET Data Services<span>  </span></span>

<span lang="EN-US">Authorization: Bearer &lt;token value&gt;<span>  </span></span>

&nbsp;

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">All the operations that are possible on a Channel, are available in the REST API documentation here<span>  </span>https://docs.microsoft.com/en-us/rest/api/media/operations/channel</span></span>

<span lang="EN-US" style="margin: 0px;line-height: 107%;font-family: 'Calibri',sans-serif;font-size: 11pt"><span style="color: #000000">If you would like to create a channel from the portal or AMS<span>  </span>explorer, you can input the same informations leveraging t<span lang="EN-US"><span>he user interface.</span></span></span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">A Channel is associated with one or more Program. A Program is an entity that you can use to control the publishing of the streaming and the storage of segments in a live stream, to ingest the content in streaming. Channels manage programs. The channel and program relationship is similar to traditional media, where a channel has a constant stream of content and a program is scoped to some timed event on that channel. You can have multiple programs for every channel. </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">A Program enables you to control the publishing and storage of segments in a live stream. Programs can run concurrently. This allows you to publish and archive different parts of the event as needed.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">For every Program is created an Asset that is stored in the Azure Storage. An Asset is an entity that rappresent a group of files and manifest that contains your video content , in this case ingested from the channel with the Program configured. When you create a Program you have to specify the channel connected to the program and the AssetId that can be created and connected to the program. You can specify in the Program configuration, the number of hours you want to retain the recorded content for the program by setting the ArchiveWindowLength property (up to 25 hours, min 5 minutes). Clients can seek through the archived content for the specified number of hours. If the program runs longer than the specified ArchiveWindowLength, the older content is removed. For example if you set 5 minutes of archive, only the last five minutes remain in the asset connected to the Program and are available for the client during the live and on-demand, when the Program will be stopped. Also if you delete a Program, you can decide to maintain the asset in the storage and reuse it to republish on-demand or to create sub-clipping.</span></span>

<span style="font-family: Calibri"><span lang="EN-US"><span style="color: #000000">Also for the program you can leverage AMS REST API, Azure Portal , MS Explorer sample application or one of the SDK for AMS .<span>  </span>More information about how to use the REST API to manage program are available here </span></span><a href="https://docs.microsoft.com/en-us/rest/api/media/operations/program"><span lang="EN-US">https://docs.microsoft.com/en-us/rest/api/media/operations/program</span></a><span lang="EN-US"><span style="color: #000000"> </span></span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"><img width="972" height="619" class="aligncenter" src="https://msdnshared.blob.core.windows.net/images/postliveams1p3.jpg" /> </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">Below a sample of REST API call to create a Program:</span></span>

<span lang="EN-US">POST https://&lt;accountname&gt;.restv2.&lt;location&gt;.media.azure.net/api/Programs HTTP/1.1<span>  </span></span>

<span lang="EN-US">DataServiceVersion: 3.0;NetFx<span>  </span></span>

<span lang="EN-US">MaxDataServiceVersion: 3.0;NetFx<span>  </span></span>

<span lang="EN-US">Accept: application/json;odata=minimalmetadata<span>  </span></span>

<span lang="EN-US">Accept-Charset: UTF-8<span>  </span></span>

<span lang="EN-US">x-ms-version: 2.11<span>  </span></span>

<span lang="EN-US">Content-Type: application/json;odata=minimalmetadata<span>  </span></span>

<span lang="EN-US">Host: &lt;host URI&gt;<span>  </span></span>

<span lang="EN-US">User-Agent: Microsoft ADO.NET Data Services<span>  </span></span>

<span lang="EN-US">Authorization: Bearer &lt;token value&gt;<span>  </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">{"Id":null,"Name":"testprogram001","Description":"","Created":"0001-01-01T00:00:00","LastModified":"0001-01-01T00:00:00","ChannelId":"nb:chid:UUID:83bb19de-7abf-4907-9578-abe90adfbabe","AssetId":"nb:cid:UUID:bc495364-5357-42a1-9a9d-be54689cfae2","ArchiveWindowLength":"PT1H","State":null,"ManifestName":null}</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">If successful, a 202 Accepted status code is returned along with a representation of the created entity in the response body.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">As you can see to create a Program you need to pass a name for the Program, the ChannelId of the Channel connected to the program and where the program ingest the video input.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">A program can be in different state:</span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Running : the program starts to ingest the signal from the channel and memorize it in the asset. If the program is published with a Locator, in this state the live content is available though the locator and also the Window Archive content on-demand already ingested </span></span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Starting : the program is starting</span></span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Stopped: the program is stopped and the ingest from the channel is stopped . In this state if the Program is published with a locator permit to reproduce on-demand the content ingested and the live is stopped</span></span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Stopping : the program are stopping</span></span></span>

<span lang="EN-US"><span><span style="color: #000000;font-family: Calibri"> </span></span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">As mentioned before an Asset represents a set of files that contains the video that the Program ingested from the channel. You can manage the configuration about Assets with the specific REST API<span>  </span>or as usual Azure Portal , MS Explorer sample application or one of the SDK for AMS .<span>  </span>More information about how to use the REST API to manage Asset is https://docs.microsoft.com/en-us/rest/api/media/operations/asset<span>  </span>.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">Another important concept in the picture of Live Streaming in AMS is the Locator that you can associate to an Asset connected to a Program. The Locator is an entity that represents the publishing <span> </span>information that are used to permit the access to the content from a specific URL published through a Streaming Endpoint in AMS and that can permit the streaming publishing.</span></span>

<span style="font-family: Calibri"><span lang="EN-US"><span style="color: #000000">More information about how to use the REST API to manage Locator is </span></span><a href="https://docs.microsoft.com/en-us/rest/api/media/operations/locator"><span lang="EN-US">https://docs.microsoft.com/en-us/rest/api/media/operations/locator</span></a><span lang="EN-US"><span style="color: #000000"> . There are different types of Locator in Azure Media Service, but for a Live Streaming, when you create a Locator for an Asset connected to a Program, you have to create a streaming Locator.</span></span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">Before to create a Locator you have to define and AccessPolicy that contains the information about the duration of the Locator is available.</span></span>

<span lang="EN-US"><span style="font-family: Calibri"><span style="color: #000000">More information about how to use the REST API to manage Access Policy is </span><a href="https://docs.microsoft.com/en-us/rest/api/media/operations/accesspolicy">https://docs.microsoft.com/en-us/rest/api/media/operations/accesspolicy</a></span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>

<img width="1333" height="597" class="aligncenter" src="https://msdnshared.blob.core.windows.net/images/postliveams1p4.jpg" />

&nbsp;

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">To create an AccessPolicy you can use a POST like in the follow example</span></span>

<span lang="EN-US">POST https://&lt;accountname&gt;.restv2.&lt;location&gt;.media.azure.net/api/AccessPolicies HTTP/1.1<span>  </span></span>

<span lang="EN-US">Content-Type: application/json;odata=verbose<span>  </span></span>

<span lang="EN-US">Accept: application/json;odata=verbose<span>  </span></span>

<span lang="EN-US">DataServiceVersion: 3.0<span>  </span></span>

<span lang="EN-US">MaxDataServiceVersion: 3.0<span>  </span></span>

<span lang="EN-US">x-ms-version: 2.11<span>  </span></span>

<span lang="EN-US">Authorization: Bearer &lt;token value&gt;<span> </span></span>

<span lang="EN-US">Host: media.windows.net<span>  </span></span>

<span lang="EN-US">Content-Length: 67<span>  </span></span>

<span lang="EN-US">Expect: 100-continue<span>  </span></span>

<span lang="EN-US"> </span>

<span lang="EN-US">{</span>

<span lang="EN-US"><span>      </span>"Name": "StreamingAccessPolicy-test001", </span>

<span lang="EN-US"><span>      </span>"DurationInMinutes" : "525600", </span>

<span lang="EN-US"><span>      </span>"Permissions" : 1 </span>

<span lang="EN-US">}<span>  </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">The Permissions value can be one of the follow values and t</span></span><span lang="EN-US" style="margin: 0px;color: black;line-height: 107%;font-family: 'Segoe UI',sans-serif;font-size: 10.5pt">his value specifies the access rights the client has when interacting with the Asset. Valid values are:</span>
<span style="font-family: Calibri"><span style="color: #000000">
<span>- None = 0</span>
<span>- Read = 1</span>
<span>- Write = 2</span>
<span>- Delete = 4</span>
<span>- List = 8</span></span></span><span lang="EN-US"></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">To create a Locator you can use a POST like<span>  </span>in the follow example:</span></span>

<span lang="EN-US">POST https://&lt;accountname&gt;.restv2.&lt;location&gt;.media.azure.net/api/Locators HTTP/1.1<span>  </span></span>

<span lang="EN-US">Content-Type: application/json;odata=verbose<span>  </span></span>

<span lang="EN-US">Accept: application/json;odata=verbose<span>  </span></span>

<span lang="EN-US">DataServiceVersion: 3.0<span>  </span></span>

<span lang="EN-US">MaxDataServiceVersion: 3.0<span>  </span></span>

<span lang="EN-US">x-ms-version: 2.11<span>  </span></span>

<span lang="EN-US">Authorization: Bearer &lt;token&gt;</span>

<span lang="EN-US">Host: media.windows.net<span>  </span></span>

<span lang="EN-US">Content-Length: 182<span>  </span></span>

<span lang="EN-US">Expect: 100-continue<span>  </span></span>

<span lang="EN-US">{ "AssetId" : "nb:cid:UUID:d062e5ef-e496-4f21-87e7-17d210628b7c", "AccessPolicyId": "AccessPolicyId","StartTime" : "2014-05-17T16:45:53", "Type":2}<span>  </span></span><span lang="EN-US"></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">The AssetId is the Id returned from Asset creation connected to the Program created and AccessPolicyId is the value returned from the AssetPolicy creation.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">Based on this configuration, the streaming endpoint starts to respond to the request received to the Locator url and dynamically transform the streaming in HLSv3, HLSv4 , MPEG-DASH and Smooth Streaming. </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">As mentioned before, when a program is in Running state and the Channel is receiving the video content, the streaming locator publish  the manifest in the different formats the live and the archive window. When the Program is stopped, the manifest published in the different formats contains the last archive window ingested, published on-demand and also the manifest will be cached in the streaming endpoint because the live is stopped. This is an important point that we have to remember when we will discuss about the URL of the Live Streaming. Basically a Program is thinked to ingest the content and republish it on-demand when you stop the Program. Imagine a Live Streaming of an Event , starting a Program at the begin of the event you can ingest and register the event streaming, publish it during the live with an archive window and when the event is complete, you can stop the Program and if you maintain the Locator active, automatically the event remain published ondemand on the same URL with the archive window active and live stopped and the manifest is now an on-demand content and the client that point to the same URL noe can see the content registered and consume it ondemand. If you remove the Locator the content isn’t published and you can cancel the Program and decide if you would maintain the Asset ingested in the storage for future use or not. </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">The Streaming Endpoint entity represents a streaming service that can deliver content directly to a client player application, or to a Content Delivery Network (CDN) for further distribution. As for the others entity in the architecture, you can manage the configuration about Streaming Endpoint with the specific REST API<span>  </span>or as usual Azure Portal , MS Explorer sample application or one of the SDK for AMS .<span>  </span>More information about how to use the REST API to manage Asset is https://docs.microsoft.com/en-us/rest/api/media/operations/streamingendpoint.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">The streaming delivery can use an AccessDeliveryPolicy <span> </span>defined at Asset level, to manage and control the access to the content and with an AccessDeliveryPolicy you can configure also the protection of the streaming ad apply DRM to the streaming. </span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">The platform based on the AccessDeliveryPolicy configuration apply the encryption with the Key configured and the information about the DRM applied and license server URL information.</span></span>

<img width="1338" height="654" class="aligncenter" src="https://msdnshared.blob.core.windows.net/images/postliveams1p5.jpg" />

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">As described before about the architecture of Live Streaming, the steps that you have to plan and configure to put at work a Live Streaming are:</span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Create and configure a Streaming Endpoint and the CDN when required that will be used to deliver the content to the client </span></span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Create the Channel with the configuration that you would leverage for your live streaming (pass-trough, live encoder, keyframe , etc) and start it when you are ready to send the signal.</span></span></span>

<span style="color: #000000"><span lang="EN-US"><span><span style="font-family: Calibri">-</span><span style="font: 7pt 'Times New Roman';margin: 0px">          </span></span></span><span lang="EN-US"><span style="font-family: Calibri">Create an Asset and connect it to a Program with a specific archive window, AccessPolicy and Locator . If Encryption and DRM are required before to create a Locator you can define and AssetDeliveryPolicy for the Asset connected to the Program and when you are ready to start the Program and the live streaming .</span></span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri">In this first post we started to described the concept about the Architecture of Live Streaming in Azure Media Service. In the next part of the post, we will continue to analyze more in depth the architecture and we start to create a Live Channel and configure it and after that we will see also how manage the high availability and control the locator URL and the point of attention about this point.</span></span>

<span lang="EN-US"><span style="color: #000000;font-family: Calibri"> </span></span>]]></content:encoded>
    </item>
    <item>
      <title>Using a global audio player and EE4 for live audio Smooth Streaming on Windows Phone 7</title>
      <link>https://docs.microsoft.com/archive/blogs/giuseppeguerrasio/using-a-global-audio-player-and-ee4-for-live-audio-smooth-streaming-on-windows-phone-7</link>
      <pubDate>Wed, 22 Jun 2011 07:43:00 GMT</pubDate>
      <dc:creator><![CDATA[Giuseppe Guerrasio]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuseppeguerrasio/2011/06/22/using-a-global-audio-player-and-ee4-for-live-audio-smooth-streaming-on-windows-phone-7/</guid>
      <description><![CDATA[After my previous post about Smooth Streaming on Windows Phone 7 I received questions about Live...]]></description>
      <content:encoded><![CDATA[<p>After my <a href="http://blogs.msdn.com/b/giuseppeguerrasio/archive/2010/12/06/using-smooth-streaming-media-element-for-windows-phone-7.aspx">previous post</a> about Smooth Streaming on Windows Phone 7 I received questions about Live Audio Streaming on Windows Phone 7. In particular the most recurrent questions are:</p>
<p>-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Is it possible to create a global audio player that works in every page of my application?</p>
<p>-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Is it possible use Expression Encoder 4 for Audio only Live Smooth Streaming?</p>
<p>I would try to respond to these questions starting from the first.</p>
<p>&nbsp;</p>
<p><strong>Is it possible to create a global audio player that works in every page of my application?</strong></p>
<p>I assuming that you are familiar with &nbsp;Smooth Streaming Media Element on Windows Phone, in the case that you want learn more about how use &nbsp;it you can read <a href="http://blogs.msdn.com/b/giuseppeguerrasio/archive/2010/12/06/using-smooth-streaming-media-element-for-windows-phone-7.aspx" target="_blank">my previous blog post&nbsp;about this</a>.</p>
<p>Smooth Streaming Media Element (SSME) is a UI control. In order to works it is necessary insert this in the visual tree of your page. If you insert this in the visual Tree of a page and after that your application navigates in other pages, SSME stopped. If you would create a global SSME for audio streaming that continue to works in every page of your application, the most simple thing that you can do is put it in the template of the page and take a reference to it in a property on the App object.</p>
<p>In order to understand &nbsp;how&nbsp;it is&nbsp;possible do this, you&nbsp;can create a simple Windows Phone Visual Studio project . You can start a new Windows Phone 7 project from Visual Studio using the specific template project:</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/6114.wp71.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-67/6114.wp71.PNG"><img style="display: block; max-width: 550px; margin-left: auto; margin-right: auto;" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/6114.wp71.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-67/6114.wp71.PNG" /></a></p>
<p>&nbsp;</p>
<p>And after that you can add a reference to Microsoft.Web.Media.SmoothStreaming.dll for WP7 (look&nbsp;<a href="http://blogs.msdn.com/b/giuseppeguerrasio/archive/2010/12/06/using-smooth-streaming-media-element-for-windows-phone-7.aspx" target="_blank">my previous blog post&nbsp;about this</a> for more info ):</p>
<p>&nbsp;&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/6266.wp72.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-67/6266.wp72.PNG"><img style="display: block; max-width: 550px; margin-left: auto; margin-right: auto;" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/6266.wp72.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-67/6266.wp72.PNG" /></a></p>
<p>&nbsp;&nbsp;In order to insert the Smooth Streaming Media Element in the template of the page, you have to create a new template and insert it in the app.xaml as a resource.&nbsp; To add the SSME to this template you have to add this reference to the app.xaml, in &nbsp;the &lt;Application &nbsp;tag:</p>
<p>xmlns:SSME="clr-namespace:Microsoft.Web.Media.SmoothStreaming;assembly=Microsoft.Web.Media.SmoothStreaming"</p>
<p>&nbsp;After that, you can add this new control template inside the &lt;Application.Resources&gt; tag in app.xaml:</p>
<p>&nbsp;<em>&lt;ControlTemplate x:Key="AudioPlayerContentTemplate"&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Grid x:Name="MediaElementContainer"&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- The Smooth Streaming media element used to play&nbsp;audio --&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</em></p>
<p><em>&lt;ssme:SmoothStreamingMediaElement&nbsp; Loaded="OnMediaLoaded" Height="1" Width="1"&nbsp; /&gt;</em></p>
<p><em>&nbsp;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- Added for the normal content --&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Grid x:Name="ClientArea"&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ContentPresenter /&gt;</em></p>
<p><em>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Grid&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Grid&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/ControlTemplate&gt;</em></p>
<p>&nbsp;</p>
<p>We use this control template to substitute the default template that the Phone use for the &nbsp;Root Phone Page. In the App.cs file add the code to inject the template in the method CompleteInitializePhoneApplication :</p>
<p>&nbsp;</p>
<p><i>private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Set the root visual to allow the application to render</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (RootVisual != RootFrame</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RootVisual = RootFrame;</i></p>
<p><i>&nbsp;</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Remove this handler since it is no longer needed</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RootFrame.Navigated -= CompleteInitializePhoneApplication;</i></p>
<p><i>&nbsp;</i><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>// Add this to inject the smooth streaming media element Control template</b></i></p>
<p><b><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RootFrame.Template = App.Current.Resources["AudioPlayerContentTemplate"]</i></b></p>
<p><b><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as ControlTemplate;</i></b></p>
<p><b><i>&nbsp;</i></b><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</i></p>
<p>&nbsp;</p>
<p>In App.cs we can also add a property that can permit to access to the SSME loaded in the template and the event to load it from the template that we have declared in the template xaml listed before. We set also the SmoothStreamingPlaybackMode&nbsp; to PlaybackMode.AudioOnly, in order to ask to SSME to download only audio chunk and ignore video tracks that could be presents in the manifest: &nbsp;</p>
<p>&nbsp;</p>
<p><i>private static SmoothStreamingMediaElement _globalMediaElement = null;</i></p>
<p><i>&nbsp;</i><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static SmoothStreamingMediaElement GlobalMediaElement</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get { return _globalMediaElement; }</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</i></p>
<p><i>&nbsp;</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void OnMediaLoaded(object sender, RoutedEventArgs e)</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (_globalAudioElement == null)</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _globalAudioElement = sender as SmoothStreamingMediaElement;</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _globalAudioElement.SmoothStreamingPlaybackMode = PlaybackMode.AudioOnly;</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</i></p>
<p>&nbsp;</p>
<p>After that, you can access from every page of the page&nbsp; to App.GlobalMediaElement and use it to set the SmoothStreamingSource and control Play and Stop.</p>
<p>For example you can add this to the LoadedEvent in the mainpage of your application, in order to start the stream:</p>
<p>&nbsp;</p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((App.GlobalAudioElement.CurrentState == SmoothStreamingMediaElementState.Stopped) || (App.GlobalAudioElement.CurrentState == SmoothStreamingMediaElementState.Closed))</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; App.GlobalAudioElement.SmoothStreamingSource = new Uri(<a href="http://server/live/audiolivestream/Manifest">http://server/live/audiolivestream.isml/Manifest</a>);</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</i></p>
<p><i>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</i></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>Is it possible use Expression Encoder 4 for Audio only Live Smooth Streaming?</strong></p>
<p>Yes,&nbsp; it is possible use Expression Encoder 4 Pro Sp1 to stream audio only live Smooth Streaming. You can also use others encoders compatible with Smooth Streaming for delivering&nbsp;Live&nbsp;Audio&nbsp;with this type of streaming.&nbsp;The current version of&nbsp;Smooth Streaming&nbsp; supports the adaptive streaming capability&nbsp; only for the&nbsp;video tracks. You can insert more audio&nbsp;tracks but&nbsp;these tracks can't&nbsp; be used for adapt the quality to the avaliable bandwith but only as alternative tracks that the user can select ( <a href="http://blogs.msdn.com/b/giuseppeguerrasio/archive/2011/01/08/multi-language-audio-with-iis-smooth-streaming-an-example-from-radiovaticana-live-streaming.aspx" target="_blank">for example different languages tracks</a> ). EE4 SP1 doesn't support multi audio track and if you need to insert more track you have to use a different encoder&nbsp;that support this or you can create more streams with separate manifests with EE4.</p>
<p>&nbsp;&nbsp;The current version of EE4 Pro Sp1 dosen't permit to create a live smooth streaming project without a video track,&nbsp; but you can insert a&nbsp;black screen video track and ignore it&nbsp;on a client side.&nbsp;In order to do that you have to select in the live project only the audio input and inserting in the manifest also one video track, that stream a black screen with a low bitrate. In the player based on SSME on the Windows Phone, or on in Silverlight for PC&nbsp;if you set the property SmoothStreamingPlaybackMode to PlaybackMode.AudioOnly, before to set the SmoothStreamingSource property, Smooth Streaming Media Element download only the audio track and ignore the video track that you have inserted in the manifest.</p>
<p>&nbsp;In order to configure EE4 Pro SP1 to deliver&nbsp;this in order to use Audio only live Smooth Streaming with IIS Media Services&nbsp;you need to use a PC with IIS Media Services 4 and EE4 Pro SP1.If you aren't familiar with Live Smooth Streaming, you can find more information about how configure IIS Media Services and Expression Encoder 4Pro SP1 for Live Smooth Streaming <a href="http://learn.iis.net/page.aspx/620/getting-started-with-iis-live-smooth-streaming/" target="_blank">in this tutorial </a>.</p>
<p>You&nbsp;can start a new EE4 project and select a Live Broadcasting project:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/0676.ee41.JPG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/0676.ee41.JPG"><img style="display: block; margin-left: auto; margin-right: auto;" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/0676.ee41.JPG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/0676.ee41.JPG" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;Add a Live Source:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/5516.ee42.JPG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/5516.ee42.JPG"><img style="display: block; margin-left: auto; margin-right: auto;" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/5516.ee42.JPG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/5516.ee42.JPG" /></a></p>
<p>Select only the audio device input:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/7485.EE43.JPG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/7485.EE43.JPG"><img style="display: block; margin-left: auto; margin-right: auto;" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/7485.EE43.JPG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/7485.EE43.JPG" width="380" height="242" /></a></p>
<p>Select from the preset for the project the H264 IIS Smooth Streaming for Windows Phone 7&nbsp;presets&nbsp;and reduce the video tracks to only one wher you select a low resolution with a low frame rate:</p>
<p>&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/6278.EE44.JPG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/6278.EE44.JPG"><img style="display: block; margin-left: auto; margin-right: auto;" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/6278.EE44.JPG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/6278.EE44.JPG" width="296" height="827" /></a></p>
<p>connect the output of EE4 to a publishing point on IIS Media Services and start the encoding ( if you aren't familiar with Live Smooth Streaming, &nbsp;you can find more information about&nbsp; how configure IIS Media Services and Expression Encoder 4Pro SP1 for Live Smooth Streaming &nbsp;<a href="http://learn.iis.net/page.aspx/620/getting-started-with-iis-live-smooth-streaming/" target="_blank">in this tutorial </a>):</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/0045.ee41.JPG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/0045.ee41.JPG"></a>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/5037.EE45.JPG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/5037.EE45.JPG"><img style="display: block; margin-left: auto; margin-right: auto;" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/5037.EE45.JPG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/5037.EE45.JPG" width="316" height="708" /></a></p>
<p>&nbsp;</p>
<p>Now you can set the url of the publishing point in the SSME player on Windows Phone 7 and pay attention to&nbsp;&nbsp;set the property SmoothStreamingPlaybackMode to PlaybackMode.AudioOnly, before to set the SmoothStreamingSource property, and you are able to Play the Live Audio only Smooth Streaming.</p>
<p>Enjoy !!!</p>]]></content:encoded>
    </item>
    <item>
      <title>Monitoring and Management services in IIS Transform Manager  1.0  Beta</title>
      <link>https://docs.microsoft.com/archive/blogs/giuseppeguerrasio/monitoring-and-management-services-in-iis-transform-manager-1-0-beta</link>
      <pubDate>Fri, 17 Jun 2011 08:29:00 GMT</pubDate>
      <dc:creator><![CDATA[Giuseppe Guerrasio]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuseppeguerrasio/2011/06/17/monitoring-and-management-services-in-iis-transform-manager-1-0-beta/</guid>
      <description><![CDATA[IIS Transform Manager 1.0 &ndash; Beta refresh is available for download. IIS Transform Manager (IIS...]]></description>
      <content:encoded><![CDATA[<p>IIS Transform Manager 1.0 &ndash; Beta refresh is <a href="http://www.iis.net/download/TransformManager">available for download</a>. IIS Transform Manager (IIS TM) is a new component of the next version of the IIS Media Services platform and provides a simple integrated video encoding/encrypting and batch conversion and transformation of video files. IIS Transform Manager integrates directly with Expression Encoder 4 to allow you to use "watch folders" to queue up multiple encode jobs on your server and deliver them directly to IIS Media Services 4.0 Web folders as IIS Smooth Streaming presentations. Transform Manager offers also an SDK that permits developers to write custom Task plug-ins that can be used with Transform Manager to support custom actions, third-party encoders, or your own custom workflows.&nbsp; IIS TM&nbsp; can permit to you an easly scalability for your transformations workflow because you could leverage Windows server HPC (<a href="http://www.microsoft.com/hpc/">High Performance Computing</a>)&nbsp; and scale out your encoding\trans-mux tasks on a grid of servers in easy way. In the next picture you can see the typical architecture that you can implement&nbsp;using IIS TM:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/4152.iistm1.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/4152.iistm1.jpg"><img style="display: block; margin-left: auto; margin-right: auto;" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/4152.iistm1.jpg" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/4152.iistm1.jpg" /></a></p>
<p>As I have written in others articles in Italy we have some important customers that use today IIS TM Beta in some&nbsp;relevant video service like <a href="http://blogs.msdn.com/b/giuseppeguerrasio/archive/2010/07/25/replaytv-service-on-rai-tv-web-site-with-silverlight-and-iis-smooth-streaming.aspx">RAI Replay TV</a> and <a href="http://blogs.msdn.com/b/giuseppeguerrasio/archive/2011/02/05/iis-media-services-4-integrated-media-platform-streaming-for-pc-windows-phone-and-iphone-ipad-with-a-single-platform-a-good-example-from-mediaset-rti-new-media.aspx">Video Mediaset web site</a>.</p>
<p>You can learn more about IIS TM starting from <a href="http://www.iis.net/download/TransformManager">the page dedicated to this new service on IIS Media Sevices Web site</a>.</p>
<p>With this new Beta coming some new interesting features in IIS TM like the new Notifications service and the Monitoring and Management API.</p>
<p>Notifications service can permit to you to send notifications as a POST web requests with job status changes to a remote web application or service. This enables web developers to build a custom Transform Manager job-monitoring system. You can learn more about notifications in IIS TM <a href="http://learn.iis.net/page.aspx/1031/sending-transform-manager-job-status-notifications-to-a-remote-web-application/">in this tutorial</a> on IIS Media Web site.</p>
<p>The new Monitoring and Management API can permit to manage Jobs using custom code. You can directly use the same API that the Management Console application uses, in order to create custom code to manage and monitoring Jobs Status and IIS TM configuration. You can send any command to IIS TM from your code and execute operation like stopping or resubmiting a Job. These API are available as WCF endpoints. You have to use a process that runs in the context of a user with administrative privilege to use these endpoints.</p>
<p>Before to start to use IIS TM and this features make sure that you have downloaded the latest IIS TM Beta build (build 1151.5) &nbsp;from the Microsoft download center in order to have the right build where this API works with the right behavior.</p>
<p>The interfaces of this API are described in the <a href="http://msdn.microsoft.com/en-us/library/microsoft.web.media.transformmanager.transformmanagerservice(v=VS.90).aspx">IIS TM SDK</a> and these offering a large numbers of methods useful to manage and monitoring Jobs and IIS TM configurations.</p>
<p>&nbsp;You can consume these WCF Endpoints in a very simple way using Visual Studio 2010. For example you can build in a very&nbsp;simple way a WPF app that is able to consume these API.</p>
<p>In order to do this you can open Visual Studio using &ldquo;run as Administrator&rdquo; in order to have the right permissions to consume management and monitoring API:</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/3362.iistm2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/3362.iistm2.png"><img style="display: block; margin-left: auto; margin-right: auto;" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/3362.iistm2.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/3362.iistm2.png" width="347" height="423" /></a></p>
<p></p>
<p>&nbsp;From Visual Studio you have to create a new WPF project:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/8204.iistm3.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/8204.iistm3.jpg"><img style="display: block; margin-left: auto; margin-right: auto;" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/8204.iistm3.jpg" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/8204.iistm3.jpg" /></a></p>
<p>In the Solution Explorer you can add a Service reference to the management and monitoring API on the PC where you running the IIS TM and Visual Studio:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/3108.iistm4.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/3108.iistm4.jpg"><img style="display: block; margin-left: auto; margin-right: auto;" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/3108.iistm4.jpg" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/3108.iistm4.jpg" width="500" height="382" /></a></p>
<p><br />&nbsp;</p>
<p>The addresses of the WCF endpoints are:</p>
<p>net.tcp://localhost:59999/TransformManager/Management/Monitoring</p>
<p>&nbsp;net.tcp://localhost:59999/TransformManager/Management/Management</p>
<p>&nbsp;and the metadata URL where is available the WSDL is:</p>
<p>net.tcp://localhost:59999/TransformManager/Management/mex</p>
<p>You can use the metadata URL and insert it in the service reference wizard that creates for you the WCF proxy code to access to the services endpoints:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/1526.iistm5.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/1526.iistm5.jpg"><img style="display: block; margin-left: auto; margin-right: auto;" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/1526.iistm5.jpg" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/1526.iistm5.jpg" /></a></p>
<p>&nbsp;</p>
<p>After the creation of the WCF proxy, you can add a reference to the WCF proxy namespace to your WPF window code, in my case ia called the namespace of the project IISTMTest and the namespace of the proxy ServiceReference1:</p>
<p><strong><em>using IISTMTest.ServiceReference1;</em></strong></p>
<p>&nbsp;and you can use the proxy classes ManagementServiceClient and&nbsp; MonitoringServiceClient in order to consume the IIS TM services.</p>
<p>For Example , you can add a Button and a ListBox with a DataTemplate &nbsp;to the WPF Window &nbsp;in order to show some details from the Jobs:</p>
<p>&nbsp;</p>
<p><em>&lt;Window x:Class="IISTMTest.MainWindow"</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;Title="MainWindow" Height="350" Width="525"&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp; &lt;Grid&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="22,12,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" /&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ListBox&nbsp;&nbsp;&nbsp; &nbsp;Height="100" HorizontalAlignment="Left" Margin="12,73,0,0" Name="listBox1" VerticalAlignment="Top" Width="479" &gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ListBox.ItemTemplate&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;DataTemplate&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Grid&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Grid.ColumnDefinitions&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ColumnDefinition Width="Auto"/&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ColumnDefinition Width="Auto"/&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ColumnDefinition Width="Auto"/&gt;</em></p>
<p><em>&nbsp;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Grid.ColumnDefinitions&gt;&nbsp;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock Margin="10,0,0,0" Grid.Column="0" &nbsp;Text="{Binding JobSchedulerId}"/&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock &nbsp;Margin="10,0,0,0" Grid.Column="1" Text="{Binding JobSchedulerName}"/&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;TextBlock &nbsp;Margin="10,0,0,0" Grid.Column="2" &nbsp;Text="{Binding EndTime}"/&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Grid&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/DataTemplate&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/ListBox.ItemTemplate&gt;&nbsp;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/ListBox&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp; &lt;/Grid&gt;</em></p>
<p><em>&lt;/Window&gt;</em></p>
<p><em>&nbsp;</em></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>and in the click event of the button you can write this code:</p>
<p>&nbsp;</p>
<p><strong><em>&nbsp;private void button1_Click(object sender, RoutedEventArgs e)</em></strong></p>
<p><strong><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</em></strong></p>
<p><strong><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MonitoringServiceClient svc = new MonitoringServiceClient();</em></strong></p>
<p><strong><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</em></strong></p>
<p><strong><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int num=svc.GetJobCountByStatus(JobStatus.Finished);</em></strong></p>
<p><strong><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JobDetails[]&nbsp; jobs =svc.GetJobDetails(JobStatus.Finished,JobDetailsField.JobSchedulerId, true, 0, num);</em></strong></p>
<p><strong><em>&nbsp;</em></strong></p>
<p><strong><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</em></strong></p>
<p><strong><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; listBox1.ItemsSource = jobs;&nbsp;&nbsp;</em></strong></p>
<p><strong><em>&nbsp;</em></strong></p>
<p><strong><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</em></strong></p>
<p><strong><em>&nbsp;</em></strong></p>
<p>And in this way you could list all the finished Jobs and show some properties about these in the ListBox.</p>
<p>In the IIS TM SDK you can find all the methods available from&nbsp; <a href="http://msdn.microsoft.com/en-us/library/microsoft.web.media.transformmanager.imanagementservice(v=VS.90).aspx" target="_blank">IManagementService</a> and&nbsp;&nbsp; <a href="http://msdn.microsoft.com/en-us/library/microsoft.web.media.transformmanager.imonitoringservice(v=VS.90).aspx" target="_blank">IMonitoringService</a> that you can call using the WCF Proxy classes created from the WSDL of the IIS TM service&nbsp;using the Visual Studio service reference wizard.</p>
<p>Because the methods from the services require that the process that call the services run in the context of a user with administrative elevated privilege, in order to&nbsp; run the exe compiled, you have also to add a .manifest file with the configuration that required the administrative privilege for the .exe. For this reason you have to add&nbsp; a new item to the project&nbsp; and insert an app.manifest file:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/8228.iistm6.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/8228.iistm6.jpg"><img style="display: block; margin-left: auto; margin-right: auto;" border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/8228.iistm6.jpg" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-61-67/8228.iistm6.jpg" /></a></p>
<p>In the manifest file you have to configure the requestedExecutionLevel in order to require administrative privilege:</p>
<p><em>&lt;?xml version="1.0" encoding="utf-8"?&gt;</em></p>
<p><em>&lt;asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;</em></p>
<p><em>&nbsp; &lt;assemblyIdentity version="1.0.0.0" name="MyApplication.app"/&gt;</em></p>
<p><em>&nbsp; &lt;trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp; &lt;security&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- UAC Manifest Options</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If you want to change the Windows User Account Control level replace the</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; requestedExecutionLevel node with one of the following.</em></p>
<p><em>&nbsp;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;requestedExecutionLevel&nbsp; level="asInvoker" uiAccess="false" /&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;requestedExecutionLevel&nbsp; level="requireAdministrator" uiAccess="false" /&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;requestedExecutionLevel&nbsp; level="highestAvailable" uiAccess="false" /&gt;</em></p>
<p><em>&nbsp;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Specifying requestedExecutionLevel node will disable file and registry virtualization.</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If you want to utilize File and Registry Virtualization for backward</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; compatibility then delete the requestedExecutionLevel node.</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>&nbsp;&nbsp; &lt;requestedExecutionLevel level="requireAdministrator" uiAccess="false" /&gt;</strong></em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/requestedPrivileges&gt;</em></p>
<p><em>&nbsp; &nbsp;&nbsp;&lt;/security&gt;</em></p>
<p><em>&nbsp; &lt;/trustInfo&gt;</em></p>
<p>&nbsp;</p>
<p><em>&lt;/asmv1:assembly&gt;</em></p>
<p>&nbsp;</p>
<p>&nbsp;After this you can run directly the .exe file.</p>
<p>Enjoy this new API from IIS TM and start to build great applications for managing videos workflow !!</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>JSDay Talks</title>
      <link>https://docs.microsoft.com/archive/blogs/giuseppeguerrasio/jsday-talks</link>
      <pubDate>Thu, 12 May 2011 04:59:00 GMT</pubDate>
      <dc:creator><![CDATA[Giuseppe Guerrasio]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuseppeguerrasio/2011/05/12/jsday-talks/</guid>
      <description><![CDATA[JSDay Talks:
&nbsp;Using today HTML5 Video 
The new HTML5 video and audio tags from the HTML5...]]></description>
      <content:encoded><![CDATA[<p>JSDay Talks:</p>
<p>&nbsp;<span style="text-decoration: underline;"><strong><span style="font-size: small;">Using today HTML5 Video </span></strong></span></p>
<p>The new HTML5 video and audio tags from the HTML5 specification offer a new powerful way to deliver multimedia content using directly HTML and JS . How we can start to use this new features in our web sites ? In this session we will analyze how to use them to play media in modern browsers and on mobile devices. Learn the most advanced techniques and best practices, including encoding and distribution, custom skinnable players, full screen workarounds, seeking settings and fallback scenarios for legacy browsers.. </p>
<p><a target="_blank" href="http://cid-d82de3153feb12ed.office.live.com/view.aspx/Public/pinningdemo/video-jsday.pptx">download slides</a> </p>
<p>&nbsp;</p>
<p><span style="text-decoration: underline;"><span style="font-size: small;"><strong>HTML5, CSS3 &ndash; Opening A Whole New World</strong></span></span></p>
<p>&nbsp;New web standards like HTML5, CSS3, and ECMAScript, web designers and developers now have a whole new set of tools they can use to build a new class of web applications that are graphically rich and have more immersive experiences than ever before. But do you really know what this new class of HTML5 web applications is capable of? What&rsquo;s in HTML5 that lets us take our sites to the next level? Let&rsquo;s find out! </p>
<p><a target="_blank" href="http://cid-d82de3153feb12ed.office.live.com/view.aspx/Public/pinningdemo/html5-jsday.pptx">download slides</a></p>
<p>&nbsp;</p>
<p><span style="text-decoration: underline;"><strong><span style="font-size: small;">&nbsp;The new Internet Explorer: Standards, Performance, Security and the new JavaScript Engine</span></strong></span></p>
<p>&nbsp;Internet Explorer 9 is here and it is a big step forward for Windows&rsquo;s browser. Main areas of improvements for IE9 are: Standards, Performance and Security. In this session we will see how Internet Explorer 9 allows developers to build new and exciting web sites using open web standards like HTML5, CSS3 and more. Today&rsquo;s websites and browsers only use 10% of what your PC offers, but with Internet Explorer 9 you can tap into the power of Windows and your whole PC so your websites look and perform as if they were native to Windows with GPU accelerations and the new JavaScript engine. And because it&rsquo;s build on standards, the same markup you write not only works across the web, but runs faster and delivers a richer experience through Windows and Internet Explorer 9 and 10!. </p>
<p><a target="_blank" href="http://cid-d82de3153feb12ed.office.live.com/view.aspx/Public/pinningdemo/IE-jsday.pptx">download slides</a></p>]]></content:encoded>
    </item>
    <item>
      <title>W3C Navigation timing raggiunge lo stato di Candidate Raccomandation</title>
      <link>https://docs.microsoft.com/archive/blogs/giuseppeguerrasio/w3c-navigation-timing-raggiunge-lo-stato-di-candidate-raccomandation</link>
      <pubDate>Fri, 25 Mar 2011 02:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Giuseppe Guerrasio]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuseppeguerrasio/2011/03/25/w3c-navigation-timing-raggiunge-lo-stato-di-candidate-raccomandation/</guid>
      <description><![CDATA[Sono trascorse solo poche settimane dal post che ho scritto relativamente alle API &nbsp;Navigation...]]></description>
      <content:encoded><![CDATA[<p>Sono trascorse solo poche settimane <a target="_blank" href="http://blogs.msdn.com/b/giuseppeguerrasio/archive/2010/11/17/internet-explorer-9-misurare-le-performance-nelle-pagine-web.aspx">dal post che ho scritto</a> relativamente alle API &nbsp;<a target="_blank" href="https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html">Navigation Timing</a> che abbiamo gi&agrave; la specifica in candidate raccomandation, <a target="_blank" href="http://blogs.msdn.com/b/ie/archive/2011/03/18/a-web-standard-quickly-w3c-navigation-timing-reaches-candidate-recommendation.aspx">come scrive anche il blog ufficiale di IE</a> a volte le specifiche negli enti di standardizzazione riescono a viaggiare velocemente ed a trovare una convergenza rapida all'interno del working group che le segue (Web Performance working group). Solo sei mesi fa la specifica era nello stato di <a target="_blank" href="http://blogs.msdn.com/b/ie/archive/2010/09/13/web-standards-from-working-draft-to-recommendation.aspx">Working Draft to&nbsp;Raccomandation</a>&nbsp;e in poco tempo tutti gli attori del&nbsp;working group da&nbsp;rappresentanti di Opera ,&nbsp;Google, Mozilla e Microsoft hanno lavorato convergendo sulla specifica.&nbsp;Lo stato di Candidate Raccomandation significa appunto che il working group considera la specifica stabile e sufficientemente matura per l'implementazione. </p>
<p>A partire dalla RC di IE9 la Navigation Timing interface &egrave; implementata senza pi&ugrave; il prefisso del vendor e potete provarla su <a target="_blank" href="http://ie.microsoft.com/testdrive/Performance/msPerformance/Default.html">questa pagina </a>del IE Test Drive</p>
<p>Il working group sta gi&agrave; lavorando a due nuove interfacce <a target="_blank" href="http://test.w3.org/webperf/specs/ResourceTiming/">Resource Timing</a>&nbsp;e <a target="_blank" href="http://test.w3.org/webperf/specs/UserTiming/">User Timing</a>&nbsp;che aggiungeranno delle&nbsp;<span title="Click for alternate translations" class="hps">funzionalit&agrave;</span> <span title="Click for alternate translations" class="hps">che</span> <span title="Click for alternate translations" class="hps">consentiranno agli sviluppatori di</span> <span title="Click for alternate translations" class="hps">misurare</span> ulteriorment <span title="Click for alternate translations" class="hps">le</span> <span title="Click for alternate translations" class="hps">prestazioni delle singole risorse</span><span title="Click for alternate translations">.</span> </p>]]></content:encoded>
    </item>
    <item>
      <title>Determinare in modo corretto la versione del browser in Internet Explorer 9</title>
      <link>https://docs.microsoft.com/archive/blogs/giuseppeguerrasio/determinare-in-modo-corretto-la-versione-del-browser-in-internet-explorer-9</link>
      <pubDate>Mon, 21 Mar 2011 13:06:00 GMT</pubDate>
      <dc:creator><![CDATA[Giuseppe Guerrasio]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuseppeguerrasio/2011/03/21/determinare-in-modo-corretto-la-versione-del-browser-in-internet-explorer-9/</guid>
      <description><![CDATA[Implementare codice dipendente dalla versione del browser e quindi effettuare quella che si chiama...]]></description>
      <content:encoded><![CDATA[<p>Implementare codice dipendente dalla versione del browser e quindi effettuare quella che si chiama "browser detection code" &egrave; una modalit&agrave; di sviluppo assolutamente da evitare, fonte di complicazioni ed errori&nbsp;come ben messo in evidenza <a target="_blank" href="http://blogs.msdn.com/b/ie/archive/2010/04/14/same-markup-writing-cross-browser-code.aspx">in questo post sul blog di IE</a>&nbsp;e come ho anche illustrato<a target="_blank" href="http://blogs.msdn.com/b/giuseppeguerrasio/archive/2010/10/13/internet-explorer-9-css-3-opacity-e-alpha-e-browser-detection-code.aspx"> in questo post sul mio blog</a> che mostra appunto un&nbsp;esempio dei possibil errori derivanti dall'utilizzo di&nbsp;questa tecnica. Ci sono per&ograve; casi in cui&nbsp;pu&ograve; essere&nbsp;utile determinare la &nbsp;versione del browser in uso. Uno dei problemi tipici che mi capita di incontrare relativamente a script sviluppati Internet Explorer &egrave; relativo appunto&nbsp;alla parte di codice che viene utilizzata per determinare la versione di IE. In&nbsp;molti casi gli sviluppatori non tengono in considerazione il comportamento di IE9 relativo alle funzionalit&agrave; di compatibilit&agrave; e quindi dei differenti document mode che il browser supporta e la modalit&agrave; con cui si applicano, scrivendo del codice che produce degli errori nel riconoscimento della versione.</p>
<p>Per determinare la versione del browser via JS si utilizzano genericamente&nbsp;le API&nbsp;&nbsp;navigator.appVersion, navigator.userAgent e&nbsp;navigator.appName&nbsp;ma spesso nel codice che viene scritto , non si tiene conto delle differenti modalit&agrave; di document mode che Internet Explorer applica, generando quindi degli script che non determinano correttamente la versione del browser. Internet Explorer pu&ograve; infatti, applicare versioni di&nbsp;document mode diverse&nbsp;in base alla struttura del DOCTYPE della pagina&nbsp;e quando&nbsp;viene abilitata la compatibility view, pu&ograve; anche inviare al Web Server uno user agent differente anche nell'header della richiesta HTTP e quindi non soltanto nelle&nbsp;API JS dell'oggetto navigator. </p>
<p>In <a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc288325(v=vs.85).aspx">questo articolo su MSDN trovate</a> un'ottima descrizione dei differenti document mode di Internet Explorer <a target="_blank" href="http://blogs.msdn.com/b/ie/archive/2010/06/16/ie-s-compatibility-features-for-site-developers.aspx">ed in questo post</a>&nbsp;una descrizione del browser mode, del ruolo della compatibility view e del document mode. Determinare il document mode che si applica nell'esecuzione di un a pagina &egrave; molto importante non solo per la versione del browser, ma anche perch&egrave; le funzionalit&agrave; di HTML5 in IE9 vengono implementate solo con l'applicazione del document mode IE9 Standard. E' possibile determinare con facilit&agrave; quale document mode o browser mode viene applicato nella navigazione con IE9 su un sito, utilizzando la developer toolbar. Facendo F12 dopo aver caricato la pagina, comparir&agrave; la developer toolbar e tra i men&ugrave; disponibili troverete anche il browser mode e il document mode che indicano le modalit&agrave; in quel momento in uso, come potete vedere nell'immagine di seguito:</p>
<p>&nbsp;<img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/8712.browsermode.JPG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-67/8712.browsermode.JPG" border="0" /></p>
<p>i men&ugrave; permettono anche di forzare l'applicazione di uno specifico browser mode o document mode.&nbsp;</p>
<p>Moltissimi script che usano la navigator.appVersion , fanno detect del numero di versione senza tener presente che in caso si applichino document mode precedenti, nella app version viene indicato come primo elemento la versione del browser verso cui il&nbsp;browser sta applicando la compatibilt&agrave;, oltre all'indicazione appunto, della versione&nbsp;del browser.&nbsp;Ad esempio nel caso di rendering di una pagina senza DOCTYPE il browser andr&agrave; a caricarla in&nbsp;quirks mode e avremo per il valore di navigator.appVersion:</p>
<p>&nbsp;"5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; .NET4.0C; .NET4.0E; InfoPath.3; MS-RTC LM 8; Zune 4.7)" </p>
<p>&nbsp;dove vedete indicato per primo&nbsp;il valore 5.0 proprio perch&egrave; si applica il document mode corrispondente appunto alla modalit&agrave; quirk e viene indicata la versione di IE9 in modalit&agrave; compatibile.</p>
<p>Per poter determinare correttamente via JavaScript la versione dl browser e distinguerla anche dal document mode in uso nella pagina &egrave; consigliabile usare una funzione come quella indicata di seguito, valida anche per le versioni precedenti e che continuer&agrave; a funzionare anche per le successive versioni di IE&nbsp;:</p>
<p><br />function getInternetExplorerVersion()<br />{<br />&nbsp; var rv = -1;&nbsp;<br />&nbsp; if (navigator.appName == 'Microsoft Internet Explorer')<br />&nbsp; {<br />&nbsp;&nbsp;&nbsp; var ua = navigator.userAgent;<br />&nbsp;&nbsp;&nbsp; var re&nbsp; = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");<br />&nbsp;&nbsp;&nbsp; if (re.exec(ua) != null)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rv = parseFloat( RegExp.$1 );<br />&nbsp; }<br />&nbsp; return rv;<br />}</p>
<p>La funzione ritorna -1 nel caso in cui il browser non &egrave; Internet Explorer, altrimenti riporta la versione del browser indipendentemente dal document mode in uso nell'esecuzione della pagina.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>HTML5:Manipolare i Pixel con il Canvas</title>
      <link>https://docs.microsoft.com/archive/blogs/giuseppeguerrasio/html5manipolare-i-pixel-con-il-canvas</link>
      <pubDate>Wed, 16 Feb 2011 01:24:00 GMT</pubDate>
      <dc:creator><![CDATA[Giuseppe Guerrasio]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuseppeguerrasio/2011/02/16/html5manipolare-i-pixel-con-il-canvas/</guid>
      <description><![CDATA[Nei precedenti post sul Canvas ho introdotto le API fondamentali del context 2D e come gestire le...]]></description>
      <content:encoded><![CDATA[<p>Nei precedenti post sul Canvas ho<a target="_blank" href="http://blogs.msdn.com/b/giuseppeguerrasio/archive/2010/12/20/html5-introduzione-al-canvas.aspx"> introdotto le API fondamentali</a> del context 2D e <a target="_blank" href="http://blogs.msdn.com/b/giuseppeguerrasio/archive/2011/01/14/html5-canvas-e-animazioni.aspx">come gestire le animazioni</a> con questo elemento&nbsp; HTML5 che&nbsp; Internet Explorer 9 possiamo sfruttare avvalendoci della accelerazione grafica garantita dal nuovo browser. </p>
<p>Un'altra interessante potenzialit&agrave; del Canvas che a partire dalla <a target="_blank" href="http://blogs.msdn.com/b/italy/archive/2011/02/10/internet-explorer-9-rc-disponibile-per-il-download-standard-velocit-224-e-sicurezza.aspx">RC di IE9</a> &egrave; stata completata e migliorata significativamente dal punto di vista delle performance, riguarda la possibilit&agrave; di utilizzare le API del Canvas che consentono via JavaScript di manipolare direttamente a livello di Pixel con un approccio RGBA il contenuto del Canvas, consentendo l'applicazione di trasformazioni e manipolazioni del contenuto, utili per costruire interessanti effetti grafici nelle nostre applicazioni Web. La principale API disponibile sul context 2D del Canvas che consente l'accesso ai pixel &egrave; il metodo <strong>getImageData(posX,posY,imgWidth,imgHeight)</strong>. Questo metodo restituisce un <strong>CanvasPixelsArray</strong> che contiene essenzialmente i pixel dell'immagine estratta&nbsp;nella propriet&agrave; data&nbsp;alla posizione e con le dimensioni passate al metodo. E' possibile accedere e modificare il contenuto dell'array contenente i pixel e&nbsp;riapplicare l'arrai con le modifiche&nbsp;ad un Canvas in una specifica posizione&nbsp;con il metodo <strong>putImageData(pixelsArray,posX,posY)</strong> .</p>
<p>Il <strong>CanvasPixelsArray</strong> consente di accedere ai pixel come abbiamo detto, con una struttura rgba.Contiene praticamente per ogni pixel 4 posizioni,&nbsp; 3 contengono rispettivamente i valori da 0 a 255 RGB e una contiene l'alpha . Ad esmpio per accedere al parametro alpha del primo pixel estratto con getImageData, occorre accedere all'elemento nella posizione 3 dell'Array, mentre ad esempio nella posizione 4 troviamo il valore R del secondo pixel estratto.</p>
<p>Di seguito abbiamo un semplice esempio che illustra praticamente l'utilizzo delle API. Nell'esempio viene&nbsp;caricata un immagine in un Canvas e poi accedendo ai pixel, invertito il valore del R di tutti i pixel e ridisegnata l'immagine manipolata nel Canvas:</p>
<p>&nbsp;&lt;!DOCTYPE html /&gt;</p>
<p>&lt;html lang="en"&gt;<br />&lt;head&gt;<br />&nbsp;&nbsp;&nbsp; &lt;title&gt;&lt;/title&gt;<br />&lt;script type="text/javascript" language="javascript"&gt;</p>
<p><br />&nbsp;&nbsp;&nbsp; this.onload = function () {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var myCanvas = document.getElementById('myCanvas');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (myCanvas.getContext) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var ctx = myCanvas.getContext("2d");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var img = new Image();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; img.src = "IELogo.png";</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; img.onload = function () {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.canvas.height = img.height;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.canvas.width = img.width;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.drawImage(img, 0, 0);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var pixelsArray = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var data = pixelsArray.data;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i = 0; i &lt; data.length; i += 4) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[i+1] = 255 - data[i]; //invert G in&nbsp;pixel<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.putImageData(pixelsArray, 0, 0);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&lt;/script&gt;</p>
<p>&lt;/head&gt;<br />&lt;body&gt;</p>
<p>&lt;canvas id="myCanvas"&gt;<br />&nbsp;Canvas is not supported.<br />&lt;/canvas&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;</p>
<p>&nbsp;Altra interessante API del Canvas che permette di estrarre i pixel e salvarli anche in un file o rileggerli come un immagine direttamente &egrave; il metodo <strong>toDataURL("image/png")</strong>&nbsp; . La specifica prevede il supporto del formato png con questo metodo e utilizzando questa API si pu&ograve; direttamente estrarre l'immagine. Ad esempio, rimanipolando l'esempio precedente possiamo aggiungere un tag image e quindi , dopo aver impostato a display:none il canvas, disegnare nel tag image il risultato della modifica dell'immagine:</p>
<p>&lt;!DOCTYPE html /&gt;</p>
<p>&lt;html lang="en"&gt;<br />&lt;head&gt;<br />&nbsp;&nbsp;&nbsp; &lt;title&gt;&lt;/title&gt;<br />&lt;script type="text/javascript" language="javascript"&gt;</p>
<p><br />&nbsp;&nbsp;&nbsp; this.onload = function () {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var myCanvas = document.getElementById('myCanvas');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var im = document.getElementById('im');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (myCanvas.getContext) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var ctx = myCanvas.getContext("2d");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var img = new Image();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; img.src = "IELogo.png";</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; img.onload = function () {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.canvas.height = img.height;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.canvas.width = img.width;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.drawImage(img, 0, 0);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var pixelsArray = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var data = pixelsArray.data;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i = 0; i &lt; data.length; i += 4) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[i + 1] = 255 - data[i]; //invert G</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.putImageData(pixelsArray, 0, 0);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; im.src&nbsp; = ctx.canvas.toDataURL("image/png");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&lt;/script&gt;</p>
<p>&lt;/head&gt;<br />&lt;body&gt;</p>
<p>&lt;canvas id="myCanvas" style="display: none"" &gt;<br />&nbsp;Canvas is not supported.<br />&lt;/canvas&gt;</p>
<p>&lt;img id="im" /&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;<br />&nbsp;</p>
<p>E' possibile anche manipolare i contenuti partendo dal catturare le immagini&nbsp;da un video in riproduzione in un tag video.&nbsp; Di seguito&nbsp; un esempio di utilizzo di questa API per ridisegnare un video che ha uno sfondo uniforme, su uno sfondo differente. Viene usata una funzione js con un interval che ogni&nbsp;50 millisecondi disegna il frame corrente del video in riproduzione su un canvas nascosto e accedendo con <b>getImage()</b> ad ogni singolo pixel, porta a zero l'alpha&nbsp;dei pixel completamente blu . La funzione&nbsp; prende poi l'immagine manipolata e la ridisegna su un canvas visibile dove viene impostata una immagine differente come background, producendo cos&igrave; la riproduzione del video nel&nbsp;Canvas&nbsp;su un background differente, utilizzando direttamente le API del browser del canvas e del tag video. </p>
<p>Di seguito il codice della pagina:</p>
<p>&lt;!DOCTYPE html&gt;<br />&lt;html&gt;<br />&lt;head&gt;<br />&nbsp;&nbsp;&nbsp; &lt;style&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; body<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; background: black;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; color: #CCCCCC;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #c2<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; background-image: url('Background.jpg');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; background-repeat: no-repeat;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; div<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; float: left;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; border: 1px solid #444444;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; padding: 10px;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; margin: 10px;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; background: #3B3B3B;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; &lt;/style&gt;<br />&nbsp;&nbsp;&nbsp; &lt;script type="text/javascript"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var processor = {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timerCallback: function () {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (this.video.paused || this.video.ended) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.computeFrame();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var self = this;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setTimeout(function () {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.timerCallback();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }, 50);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; doLoad: function () {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.video = document.getElementById("video");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.c1 = document.getElementById("c1");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.ctx1 = this.c1.getContext("2d");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.c2 = document.getElementById("c2");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.ctx2 = this.c2.getContext("2d");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var self = this;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.video.addEventListener("play", function () {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.width = self.video.videoWidth / 2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.height = self.video.videoHeight / 2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.timerCallback();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }, false);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; computeFrame: function () {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var frame = this.ctx1.getImageData(0, 0, this.width, this.height);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var l = frame.data.length / 4;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var data = frame.data;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i = 0; i &lt; l; i++) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var r = data[i * 4 + 0];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var g = data[i * 4 + 1];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var b = data[i * 4 + 2];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (g == 0 &amp;&amp; r == 0 &amp;&amp; b == 255)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data[i * 4 + 3] = 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.ctx2.putImageData(frame, 0, 0);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br />&nbsp;&nbsp;&nbsp; &lt;/script&gt;<br />&lt;/head&gt;<br />&lt;body onload="processor.doLoad()"&gt;<br />&nbsp;&nbsp;&nbsp; &lt;div&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;video id="video" src="video.mp4" controls width="336" height="256"&nbsp; /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/div&gt;<br />&nbsp;&nbsp;&nbsp; &lt;div&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;canvas id="c1" width="336" height="256" style="display: none"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/canvas&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;canvas id="c2" width="336" height="256"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/canvas&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/div&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;</p>
<p>e qui il risultato nel browser:</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/4087.videoeffect.jpg" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-67/4087.videoeffect.jpg" border="0" /></p>]]></content:encoded>
    </item>
    <item>
      <title>IIS Media Services 4 Integrated Media Platform, Streaming for PC, Windows Phone and iPhone™ / iPad™ with a Single Platform : A good example from Mediaset RTI New Media</title>
      <link>https://docs.microsoft.com/archive/blogs/giuseppeguerrasio/iis-media-services-4-integrated-media-platform-streaming-for-pc-windows-phone-and-iphone-ipad-with-a-single-platform-a-good-example-from-mediaset-rti-new-media</link>
      <pubDate>Sat, 05 Feb 2011 07:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Giuseppe Guerrasio]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuseppeguerrasio/2011/02/05/iis-media-services-4-integrated-media-platform-streaming-for-pc-windows-phone-and-iphone-ipad-with-a-single-platform-a-good-example-from-mediaset-rti-new-media/</guid>
      <description><![CDATA[One of the missions of IIS Media Services&nbsp; 4.0 (IIS MS) is to offer an Integrated Media...]]></description>
      <content:encoded><![CDATA[<p>One of the missions of IIS Media Services&nbsp; 4.0 (IIS MS) is to offer an <a target="_blank" href="http://www.iis.net/overview/IntegratedMediaPlatform">Integrated Media Platform</a> that allows users to use a single encoder and a single backend to serve video content live and on-demand to a large numbers of client devices spanning from PC , MAC, Windows Phone 7 and iPhone<sup>TM</sup>\iPad<sup>TM</sup> .</p>
<p>A good example of this capability, currently available in Italy, is from RTI New Media - Mediaset. Mediaset is one of the top broadcasters in Italy and RTI New Media inside Mediaset Group is responsible for their web video platform and in particular for video.mediaset.it web site. Video.mediaset.it publishes free live and on demand video content supported by an advertising model from main Mediaset TV channels. In addition, on the same web site RTI new media publishes daily all of the video news content for the TGCOM web site and for SportMediaset web site that are top tier web sites in Italy in terms of importance and number of visitors. Below is an image from the Mediaset web site :</p>
<p>&nbsp;<img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/3312.MEDIASET.jpg" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-67/3312.MEDIASET.jpg" border="0" /></p>
<p>&nbsp;</p>
<p>Content from the <a href="http://video.mediaset.it">http://video.mediaset.it</a>&nbsp; and&nbsp; <a href="http://www.tgcom.mediaset.it/">http://www.tgcom.mediaset.it/</a>&nbsp; web site is available on PC and Mac and for news content videos are available also on Windows Phone 7 and iPhone<sup>TM</sup> / iPad<sup>TM</sup> devices with a downloadable application. Below is an image from the Windows Phone 7 application:</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/0285.screen_tgcom.jpg" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-67/0285.screen_5F00_tgcom.jpg" border="0" /></p>
<p>The video platform in use on this Web Site is based on the IIS Media Services platform which permits the delivery of &nbsp;adaptive HTTP streaming and progressive download . Key features of the service include:</p>
<ul>
<li>&nbsp;SnackTV content that delivers free short videos from main Mediaset TV channels and leverages .mp4 and .fv4 content, delivered via IIS Media Services progressive download and <a href="http://www.iis.net/download/BitRateThrottling">Bit Rate Throttling</a> capability in IIS Media Services. </li>
<li>Full episode area (puntate intere) that deliver content from TV shows, fictions, etc. from the main Mediaset TV channels, that leverage IIS Media Services and IIS <a href="http://www.iis.net/download/SmoothStreaming">Smooth Streaming</a> and Silverlight for deliver of high quality content with the best experience for customers. Some content is also securely delivered using <a href="http://www.microsoft.com/playready/">Microsoft Playready</a> DRM for content protection. </li>
<li>Moto GP and Sport that also leverage IIS <a href="http://www.iis.net/download/SmoothStreaming">Smooth Streaming</a> , Silverlight and <a href="http://www.microsoft.com/playready/">Microsoft Playready</a> DRM for secure delivery of premium content. </li>
<li>News videos live and on demand that also leverages IIS Media Services and IIS <a href="http://www.iis.net/download/SmoothStreaming">Smooth Streaming</a> and Windows Media Services.</li>
</ul>
<p>As I described before, some video content in particular from the news area are also available on Windows Phone 7 and Apple Devices. For delivery of &nbsp;this type of content on mobile devices, RTI New Media uses <a href="http://blogs.msdn.com/b/giuseppeguerrasio/archive/2010/09/11/iis-media-services-4-integrated-media-platform-streaming-for-pc-windows-phone-tv-and-iphone-ipad-with-a-single-platform.aspx">IIS Media Services features</a> . On Windows Phone 7 the application is built using the IIS <a></a><a href="http://blogs.msdn.com/b/giuseppeguerrasio/archive/2010/09/11/iis-media-services-4-integrated-media-platform-streaming-for-pc-windows-phone-tv-and-iphone-ipad-with-a-single-platform.aspx">Smooth Streaming Client</a> and Silverlight.&nbsp; This&nbsp; combinationgives the phone the ability to stream live and on-demand adaptive HTTP content in the IIS Smooth Streaming format On Apple Devices, RTI leverage IIS Media Services new capabilities to deliver Apple HTTP live streaming format for both live and on-demand.</p>
<p>The content was encoded in Smooth Streaming format using the H.264 video codec and AAC audio, and was transmuxed (repackaged from one file format to another without re-encoding) to Apple HTTP live streaming format using the&nbsp; <a href="http://www.iis.net/download/TransformManager">IIS Transform Manager</a> (currently in Beta) , leveraging a single encoding and delivery platform.</p>
<p>IIS Transform Manager (IIS TM) &nbsp;is a new component of the next version of the IIS Media Services platform and provides not only &nbsp;Iphone/Ipad support but also a simple integrated video encoding/encrypting and batch conversion and transformation of video files. IIS Transform Manager integrates directly with Expression Encoder 4 to allow you to use "watch folders" to queue up multiple encode jobs on your server and deliver them directly to IIS Media Services 4.0 Web folders as IIS Smooth Streaming presentations. Transform Manager offer also an SDK that permits developers to write custom Task plug-ins that can be used with Transform Manager to support custom actions, third-party encoders, or your own custom workflows. Transform Manager comes with a specific task that RTI New Media leverage to convert IIS Smooth Streaming presentations directly into MPEG-2 Transport Streams in the Apple HTTP live streaming format for delivering content to Apple devices and publish it with IIS Media Services 4.0.</p>
<p>The video platform on video.mediaset.it also benefits from the use of <a href="http://www.iis.net/download/ApplicationRequestRouting">IIS Application Request Routing ( IIS ARR)</a> in order to implement a flexible and scalable HTTP edge server infrastructure. Edge caching in the HTTP delivery infrastructure provides a level of caching able to amplify content delivery capability on video.mediaset.it with the right and flexible scalability.&nbsp;&nbsp; </p>
<p>Below you can see a high level picture of the video delivery architecture:</p>
<p>&nbsp;<img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/0118.mediasetarch.jpg" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-67/0118.mediasetarch.jpg" border="0" /></p>
<p>The services delivered on video.mediaset.it from RTI new media are a great example of the integrated media platform capabilities of IIS Media Services and shows how quick it is to implement a robust and interoperable solution that simplifies the delivery of video content for both live and on-demand to a large numbers of different client devices on a single platform.&nbsp; </p>
<p>If you are looking for more details &nbsp;about the latest support for iPhone\iPad in IIS Media Services and&nbsp; IIS Transform Manager you can reference this online <a target="_blank" href="http://learn.iis.net/page.aspx/857/encode-and-deliver-on-demand-smooth-streams-with-iis-transform-manager-and-iis-media-services-4/">tutorial, "Encode and Deliver On-Demand Smooth Streams with IIS Transform Manager and IIS Media Services 4</a><span style="text-decoration: underline;">"</span> &nbsp;and for details on Live Streaming, read this <a href="http://learn.iis.net/page.aspx/854/apple-http-live-streaming-with-iis-media-services/">tutorial on Live Streaming for iPhone/iPad with IIS MS 4.0</a>.</p>
<p>To download the latest release of the IIS Media Services platform and learn more, visit <a href="http://iis.net/media">http://iis.net/media</a>&nbsp;and stay tuned for the Beta of IIS TM that coming soon&nbsp;in march\april timeframe&nbsp;!!!</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>HTML5: Un database per il browser con IndexedDB per andare oltre il Web Storage</title>
      <link>https://docs.microsoft.com/archive/blogs/giuseppeguerrasio/html5-un-database-per-il-browser-con-indexeddb-per-andare-oltre-il-web-storage</link>
      <pubDate>Fri, 21 Jan 2011 00:20:00 GMT</pubDate>
      <dc:creator><![CDATA[Giuseppe Guerrasio]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuseppeguerrasio/2011/01/21/html5-un-database-per-il-browser-con-indexeddb-per-andare-oltre-il-web-storage/</guid>
      <description><![CDATA[La possibilit&agrave; di gestire localmente nel browser uno storage per le applicazioni accessibile...]]></description>
      <content:encoded><![CDATA[<p>La possibilit&agrave; di gestire localmente nel browser uno storage per le applicazioni accessibile direttamente via JavaScript &egrave; sicuramente una delle funzionalit&agrave;&nbsp;tra le pi&ugrave; desiderate e potenzialmente utili per arricchire le applicazioni Web, incrementarne le performance,&nbsp;gestire sempre pi&ugrave; la possibilit&agrave; di scenari di offline. Un primo importante passo nelle specifiche HTML5 verso la possibilit&agrave; di utilizzare uno storage client locale &egrave; rappresentato dalle specifiche del <a href="http://www.w3.org/TR/webstorage/" target="_blank">WebStorage</a> che sono ampiamente supportate nei diversi browser e presenti anche in IE a partire dalla versione 8 . Il WebStorage permette per&ograve; di gestire la persistenza di elementi in modo simile a quanto possibile fare con cookie superando per&ograve; le limitazioni ed in particolare la complicazione non indifferente nella gestione dei cookie stessi.&nbsp;</p>
<p>Le API del Web Storage offrono essenzialmente due oggetti il <em>sessionStorage </em>e il <em>localStorage</em> che consentono di gestire un meccanismo di persistenza per dominio in modalit&agrave; per sessione o persistente. L'utilizzo &egrave; molto semplice, si usano i metodi <em>setItem </em>e <em>removeItem</em> per inserire e cancellare item utilizzando un meccanismo chiave valore . Ad esempio per inserire un valore:</p>
<p><em>localStorage.setItem("keyName","keyValue");</em></p>
<p>per rimuoverlo:</p>
<p><em>localStorage.removeItem("keyName");</em></p>
<p>Disponibili anche una buona serie di librerie che consentono di gestire il fallback sui browser che non supportano il Web Storage come ad esempio la libreria&nbsp;<a href="http://gist.github.com/350433" target="_blank">storage polyfill</a> di Remy Sharp.&nbsp;</p>
<p>&nbsp;Ampia e continua la discussione nel W3C per ampliare il supporto nel browser per lo storage locale,&nbsp;allargandolo anche alla presenza di un vero e proprio&nbsp;database semplificato&nbsp;che consenta di memorizzare e gestire dati in modo strutturato e apra la strada a scenari di sincronizzazione di dati. Tra le specifiche proposte abbiamo la Web SQL Database API e la parte di <a href="http://www.w3.org/TR/IndexedDB/" target="_blank">IndexedDB </a>. Quest'ultima &egrave; la specifica proposta da Oracle , Microsoft e Mozilla, su cui stanno convergendo la maggior parte dei membri del W3C, <a href="http://news.cnet.com/8301-30685_3-20000376-264.html?tag=mncol;title" target="_blank">convergenza gi&agrave;&nbsp;in corso come tendenza da alcuni mesi </a>e che comincia a concretizzarsi&nbsp;anche in annunci di implementazione nei browser&nbsp;<a href="http://news.cnet.com/8301-30685_3-20028379-264.html?tag=mncol;1n" target="_blank">come ad esempio per firefox</a>. Anche per chrome sta succedendo altrettanto&nbsp; con l'avvio dell'implementazione di IndexedDB e nella parte di <a href="http://www.w3.org/TR/webdatabase/" target="_blank">Web SQL Database nelle specifiche del W3C si legge</a> oramai formalmente nello status del documento: "Beware. This specification is no longer in active maintenance and the WebApplications Working Group does not intend to maintain it further"&nbsp;ed &egrave; quindi oramai IndexedDB la specifica candidata&nbsp;per l'implementazione da parte della maggior parte dei browser. Stiamo comunque parlando di specifiche di standard ancora in definizione e quindi&nbsp;immature&nbsp;per un utilizzo di applicazioni reali e che quindi vanno utilizzate con cautela, come anche i diversi vendor di browser segnalano. Ad esempio <a href="http://hacks.mozilla.org/2011/01/indexeddb-in-firefox-4/" target="_blank">in questo post sull'implementazione&nbsp;nella beta di&nbsp;firefox</a> leggiamo "Keep in mind that IndexedDB is brand new and is not uniformly supported by all browsers, and please file bugs for any behavior that seems to contradict the specification!".&nbsp;</p>
<p><span id="result_box" lang="it"><span class="hps" title="Click for alternate translations">Il</span> <span class="hps" title="Click for alternate translations">Web</span> <span class="hps" title="Click for alternate translations">&egrave; una</span> <span class="hps" title="Click for alternate translations">piattaforma</span> <span class="hps" title="Click for alternate translations">in continua evoluzione</span><span title="Click for alternate translations">,</span> <span class="hps" title="Click for alternate translations">e</span> <span class="hps" title="Click for alternate translations">ci</span> <span class="hps" title="Click for alternate translations">sar&agrave; sempre</span> <span class="hps" title="Click for alternate translations">una tensione</span> <span class="hps" title="Click for alternate translations">tra</span> <span class="hps" title="Click for alternate translations">gli sviluppatori</span> <span class="hps" title="Click for alternate translations">che desiderano</span> <span class="hps" title="Click for alternate translations">utilizzare le</span> <span class="hps" title="Click for alternate translations">tecnologie</span> <span class="hps" title="Click for alternate translations">pi&ugrave; recenti e </span><span class="hps" title="Click for alternate translations">le specifiche ufficiali</span> <span class="hps" title="Click for alternate translations">ancora non</span> <span class="hps" title="Click for alternate translations">consentono</span><span title="Click for alternate translations">, e</span> <span class="hps" title="Click for alternate translations">gli sviluppatori</span> <span class="hps" title="Click for alternate translations">di&nbsp; applicazioni di business</span> <span class="hps" title="Click for alternate translations">che</span> <span class="hps" title="Click for alternate translations">vogliono</span> <span class="hps" title="Click for alternate translations">costruire</span> <span class="hps" title="Click for alternate translations">qualcosa</span> <span class="hps" title="Click for alternate translations">per</span> <span class="hps" title="Click for alternate translations">una specifica</span> <span class="hps" title="Click for alternate translations">che si aspettano stabile e supportata&nbsp;</span><span class="hps" title="Click for alternate translations">per un</span> <span class="hps" title="Click for alternate translations">decennio</span><span title="Click for alternate translations">.</span> <span class="hps" title="Click for alternate translations">Non in tutte le situazioni&nbsp;&egrave; possibile </span><span class="hps" title="Click for alternate translations">aggiornare</span> <span class="hps" title="Click for alternate translations">i&nbsp;b</span><span class="hps" title="Click for alternate translations">rowser</span> e le applicazioni <span class="hps" title="Click for alternate translations">ogni notte</span> <span class="hps" title="Click for alternate translations">o</span> <span class="hps" title="Click for alternate translations">anche</span> <span class="hps" title="Click for alternate translations">ogni settimana, ma al tempo stesso &egrave; anche importante avere la possibilit&agrave; di valutare l'implementazione di specifiche ancora non complete e di stimolare e partecipare all'implemetazione delle stesse</span><span title="Click for alternate translations">. </span></span></p>
<p><span lang="it"><span title="Click for alternate translations"></span></span>Per permettere il test&nbsp;delle specifiche in evoluzione e garantire&nbsp;allo stesso tempo, una chiara e netta suddivisione tra le specifiche stabili ed utilizzabili e la parte di specifiche sperimentali, Microsoft sta adottando nello sviluppo di IE un approccio differente rispetto ad altri&nbsp;browser che inserisco e modificano le implementazioni direttamente nelle build , generando anche situazioni di confusione come successo recentemente con i websocket (<a href="http://hacks.mozilla.org/2010/12/websockets-disabled-in-firefox-4/">http://hacks.mozilla.org/2010/12/websockets-disabled-in-firefox-4/</a>)&nbsp;. Nelle preview e nelle beta ed a maggior ragione nelle release finali delle varie versioni di IE, vengono inserite soltanto le implementazioni delle specifiche che sono sufficientemente mature, documentate e che hanno la garanzia di un comportamento uniforme&nbsp;nelle diverse implementazioni nei vari browser. Per consentire invece, la sperimentazione anche della parte di specifiche in evoluzione e che sono candidate ad una futura implementazione uniforme, sono stati appunto creati gli <a href="http://blogs.msdn.com/b/italy/archive/2010/12/21/htlm5-labs-sviluppare-i-siti-di-oggi-e-sperimentare-da-subito-le-specifiche-html-di-domani.aspx" target="_blank">HTML5 Labs</a> . Attraverso gli HTML5 Labs si possono aggiungere al browser delle implementazioni sperimentali delle nuove specifiche e cominciare a provarle utilizzandole in modo controllato, avendo cos&igrave; una netta separazione tra gli elementi stabili da quelli in forte evoluzione, garantendo pienamente gli sviluppatori rispetto alla stabilit&agrave; e la compatibilit&agrave; delle implementazioni supportate nel browser.</p>
<p>Tra le specifiche disponibili come componenti aggiuntivi su HTML5 Labs abbiamo appunto l'implementazione di <a href="http://html5labs.interoperabilitybridges.com/prototypes/indexeddb/indexeddb/info" target="_blank">IndexedDB che possiamo scaricare</a> dal sito e registrare localmente sul nostro PC per sperimentarla utilizzando IE 9. Si come gi&agrave; detto, di una implementazione per test&nbsp; realizzata attraverso un ActiveX.&nbsp;Nel package scaricato da HTML5 Labs troviamo un readme introduttivo che spiega come configurare e registrare il componente aggiuntivo , un file js di base che carica il componente nella pagina e genera delle variabili per consentire un utilizzo diretto dei metodi dell'ActiveX da JS e una serie di esempi che illustrano il funzionamento delle API implementate al momento secondo&nbsp;.&nbsp;&nbsp;</p>
<p>&nbsp;IndexedDB prevede essenzialmente delle API con due modalit&agrave; di utilizzo: sincrono e asincrono. Si possono creare dei database locali comuni ad uno specifico dominio. Attraverso le API&nbsp;<span id="result_box" lang="it"><span class="hps" title="Click for alternate translations">si possono gestire&nbsp;</span>&nbsp;<span class="hps" title="Click for alternate translations"><span class="hps" title="Click for alternate translations">gestione</span> <span class="hps" title="Click for alternate translations">dei dati</span>&nbsp;</span> <span class="hps" title="Click for alternate translations">avanzate attraverso la&nbsp;gestione di&nbsp;indici per l'accesso ai dati. Si possono anche utilizzare delle&nbsp;</span><span class="hps" title="Click for alternate translations">transazioni per la gestione di pi&ugrave; operazioni sui dati&nbsp;</span>&nbsp;<span class="hps" title="Click for alternate translations">e vengono usati&nbsp;dei </span><span class="hps" title="Click for alternate translations">di</span> <span class="hps" title="Click for alternate translations">dati</span> <span class="hps" title="Click for alternate translations">persistenti</span> in una struttura <span class="hps" title="Click for alternate translations">B</span><span class="atn" title="Click for alternate translations">-</span><span title="Click for alternate translations">tree</span> <span class="hps" title="Click for alternate translations">che permettono in modo </span><span class="hps" title="Click for alternate translations">efficace</span>&nbsp; <span class="hps" title="Click for alternate translations">l'inserimento,</span> <span class="hps" title="Click for alternate translations">cancellazione</span><span title="Click for alternate translations">,&nbsp;e</span>&nbsp;<span class="hps" title="Click for alternate translations">accesso</span> <span class="hps" title="Click for alternate translations">in</span><span title="Click for alternate translations">-order</span> anche <span class="hps" title="Click for alternate translations">di</span> <span class="hps" title="Click for alternate translations">un numero elevato</span><span class="hps" title="Click for alternate translations">&nbsp;di record</span> <span class="hps" title="Click for alternate translations">di dati</span><span title="Click for alternate translations">.</span></span></p>
<div id="gt-res-tools" class="g-section">Di seguito riporto un semplice esempio di creazione\accesso ad un database locale con la parte di API sincrone:</div>
<div class="g-section"></div>
<div class="g-section"><em>try <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var db = indexedDBSync.open(indexedDBName, indexedDBDescription);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (db) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; db.setVersion("1.0");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var sName = db.name;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var dVersion = db.version;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var dTableNames = db.objectStoreNames;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var strNames = "IndexedDB name: "&nbsp; + sName <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + "; version: " + dVersion + "; object stores: ";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var i = 0; i &lt; dTableNames.length; i++) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strNames = strNames + dTableNames[i] + ", ";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert(strNames);</em></div>
<div class="g-section"><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; db.close();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (e) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert("Error: " + e.message);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /></em></div>
<div class="g-section"></div>
<div class="g-section"></div>
<div class="g-section"></div>
<div class="g-section">Si possono poi creare degli indici e inserire contenuti ed accederci direttamente attrraverso l'indice stesso ed il semplice esempio descrittivo che trovate nella specifica e che riporto di seguito da un idea della modalit&agrave; di utilizzo:</div>
<div class="g-section">&nbsp;</div>
<div class="g-section"><em>var db = indexedDB.open('books', 'Book store', false);<br />if (db.version !== '1.0') {<br />&nbsp; var olddb = indexedDB.open('books', 'Book store');<br />&nbsp; olddb.createObjectStore('books', 'isbn');<br />&nbsp; olddb.createIndex('BookAuthor', 'books', 'author', false);<br />&nbsp; olddb.setVersion("1.0");&nbsp; <br />}<br />// db.version === "1.0";&nbsp; <br />var index = db.openIndex('BookAuthor');<br />var matching = index.get('fred');<br />if (matching)<br />&nbsp; report(matching.isbn, matching.name, matching.author);<br />else<br />&nbsp; report(null);</em></div>
<div class="g-section">&nbsp;</div>
<div class="g-section">Nel caso di utilizzo delle API asincrone si possono impostare direttamente le funzioni su cui essere richiamati ad esecuzione ultimata come nel seguente esempio tratto sempre dal documento della specifica:</div>
<div class="g-section">&nbsp;</div>
<div class="g-section"><em>function findFred() {<br />&nbsp;&nbsp;&nbsp; var store = db.objectStore('books');<br />&nbsp;&nbsp;&nbsp; var index = store.index('BookAuthor');<br />&nbsp;&nbsp;&nbsp; var req = index.get('fred');<br />&nbsp;&nbsp;&nbsp; req.onsuccess = function(event) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var matching = event.result;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; report(matching.isbn, matching.name, matching.author);<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; req.onerror = function(event) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; report(null);<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp; }<br /></em></div>
<div class="g-section">&nbsp;</div>
<div class="g-section"></div>
<div class="g-section"></div>
<div class="g-section"></div>
<div class="g-section"></div>
<div class="g-section">Scaricando <a href="http://html5labs.interoperabilitybridges.com/prototypes/indexeddb/indexeddb/" target="_blank">l'implementazione di test da HTML5 Labs</a>, trovate ulteriori esempi per poter approfondire l'utilizzo di questa specifica in elaborazione.</div>
<div class="g-section"></div>
<div class="g-section">UPDATED 4-feb-2011:</div>
<div class="g-section">Aggiornata l'implementazione su HTML5 Labs di Indexed DB . Informazioni sull'aggiornamento nel blog <a href="http://blogs.msdn.com/b/interoperability/archive/2011/02/03/the-indexeddb-prototype-gets-an-update.aspx">http://blogs.msdn.com/b/interoperability/archive/2011/02/03/the-indexeddb-prototype-gets-an-update.aspx</a></div>]]></content:encoded>
    </item>
    <item>
      <title>HTML5:Canvas e animazioni</title>
      <link>https://docs.microsoft.com/archive/blogs/giuseppeguerrasio/html5canvas-e-animazioni</link>
      <pubDate>Fri, 14 Jan 2011 02:30:00 GMT</pubDate>
      <dc:creator><![CDATA[Giuseppe Guerrasio]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuseppeguerrasio/2011/01/14/html5canvas-e-animazioni/</guid>
      <description><![CDATA[Nel precedente post sul Canvas ho descritto l'utilizzo del nuovo tag HTML5 e le API JavaScript che...]]></description>
      <content:encoded><![CDATA[<p>Nel precedente <a target="_blank" href="http://blogs.msdn.com/b/giuseppeguerrasio/archive/2010/12/20/html5-introduzione-al-canvas.aspx">post sul Canvas</a> ho descritto l'utilizzo del nuovo tag HTML5 e le API JavaScript che permettono di programmarlo. <span class="long_text" lang="it" id="result_box"><span>Per riassumere quello che abbiamo discusso nel precedente post:<br /></span><span>- il Canvas fornisce una superficie di disegno immediato<br /></span><span>- gli sviluppatori Web utilizzano le API JS esposte dal Canvas per disegnare varie primitive grafiche direttamente sulla superfice del Canvas stesso</span></span></p>
<p><span class="long_text" lang="it"><span>Cercher&ograve; ora di introdurre le modalit&agrave; con cui &egrave; possibile gestire con JS delle animazioni sfruttando il context 2D del Canvas. La gestione delle animazioni con il Canvas pu&ograve; essere effettuata attraverso la modifica diretta del suo contenuto, sfruttando delle funzioni JS richiamate ad intervalli specifici, con una frequenza determinata in base al frame rate che si vuole ottenere nella gestione del ridisegno del movimento. Si procede in pratica &nbsp;ad intervalli con:</span></span></p>
<p><span class="long_text" lang="it"><span>- cancellare&nbsp;l'area canvas coinvolta</span></span></p>
<p><span class="long_text" lang="it"><span>- ridisegnare l'elemento nella nuova posizione</span></span></p>
<p><span class="long_text" lang="it"><span>Di seguito un semplice esempio di animazione dove abbiamo una pagina contenente un canvas&nbsp;e una funzione draw che ogni 10 millisecondi ridisegna il canvas, producendo un'animazione di scorrimento di una immagine. </span></span></p>
<p><span class="long_text" lang="it"><span></span></span></p>
<p><span class="long_text" lang="it"><span>Il processo di avvio dell'intervallo di ridisegno, viene&nbsp;eseguito solo dopo il load dell'immagine per avere tutti gli elementi, scaricati localmente e quindi utilizzabili per l'esecuzione dell'animazione.</span></span></p>
<p><span class="long_text" lang="it"><span><em>&lt;!DOCTYPE html&gt;</em></span></span></p>
<p><span class="long_text" lang="it"><span></span></span><span class="long_text" lang="it"><span><em>&lt;html lang="en"&gt;</em></span></span><span class="long_text" lang="it"><span><br /><em>&lt;head&gt;<br />&lt;title title="test anim"&gt;&lt;/title&gt;<br />&lt;meta charset="utf-8" /&gt;</em></span></span></p>
<p>&nbsp;<em>&nbsp;&lt;script language="javascript" type="text/javascript"&gt; &nbsp;<br />&nbsp;&nbsp;var myCanvas, ctx;<br />&nbsp;&nbsp;var x1=10,y1=10, distance=5;<br />&nbsp;&nbsp;var img;<br />&nbsp;&nbsp;var imgWidth;<br />&nbsp;&nbsp;var imgHeight;</em></p>
<p><em></em></p>
<p><em>&nbsp;&nbsp;window.addEventListener("DOMContentLoaded", Main, false); <br />&nbsp;&nbsp;<br />&nbsp;&nbsp;function Main(){<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;myCanvas = document.getElementById("myCanvas");<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;if (myCanvas.getContext) {<br />&nbsp;&nbsp;&nbsp;&nbsp;ctx = myCanvas.getContext("2d");<br />&nbsp;&nbsp;&nbsp;&nbsp;img = new Image();<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;img.addEventListener("load", function(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;imgWidth = 100;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;imgHeight = 100;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lastFrameTime = new Date().getTime();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setInterval(draw, 16);<br />&nbsp;&nbsp;&nbsp;&nbsp;}, false);<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;img.src = "IELogo.png";<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;</em><em>&nbsp;&nbsp;<br />&nbsp;&nbsp;function draw() {<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;y1 += distance; <br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;// make image show up again when it falls of the page<br />&nbsp;&nbsp;&nbsp;if (y1 &gt; (ctx.canvas.height - imgHeight)) {<br />&nbsp;&nbsp;&nbsp;&nbsp;y1 = 10;<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);<br />&nbsp;&nbsp;&nbsp;ctx.fillText("Sample Animation", x1, 10);<br />&nbsp;&nbsp;&nbsp;ctx.drawImage(img, x1, y1, imgWidth, imgHeight);<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;}<br />&nbsp;<br />&nbsp;&lt;/script&gt; <br />&lt;/head&gt;<br />&lt;body&gt;<br />&nbsp;<br />&lt;canvas id="myCanvas" width="500" height="500"&gt;<br />&nbsp;Canvas is not supported.<br />&lt;/canvas&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;</em></p>
<p>&nbsp;Come si vede dal codice contenuto nella funzione draw, viene usata una variabile per mantenere la posizione dell'ultimo ridisegno all'interno del canvas e, dopo aver cancellato il canvas, con le&nbsp;API del context 2D si ridisegna l'elemento&nbsp;nella nuova posizione. Richiamando la funzione draw con un intervallo di 16 millisecondi , si produce una animazione&nbsp;con teoricamente 60 frame al secondo, dipendente ovviamente dalla velocit&agrave; con&nbsp;cui il browser esegue la funzione di ridisegno.&nbsp;<span class="long_text" lang="it"><span>E' anche possibile applicare delle trasformazioni usando le&nbsp;API specifiche&nbsp;&nbsp;del canvas&nbsp;(rotate, translate, transform ) durante un'</span></span><span class="long_text" lang="it"><span>animazione per gestire il funzionamento&nbsp;della stessa. </span></span></p>
<p><span class="long_text" lang="it"><span></span></span></p>
<p><span class="long_text" lang="it"><span>Oltre alla precedente modalit&agrave; di cancellazione e riscrittura, le API del canvas offrono la possibilit&agrave; di gestire lo stato del contenuto prima di applicare un nuovo disegno. Attraverso i metodi <em>save</em> e <em>restore</em> &egrave; possibile gestire lo stato e salvarlo prima di applicare una trasformazione e con save, riportarlo nello stato precedente, funzione molto utile nel caso in cui si debba, ad esempio, ridisegnare pi&ugrave; elementi in una animazione. Ad esempio se si devono disegnare pi&ugrave; elementi in sequenza si pu&ograve; utilizzare questa funzionalit&agrave;:</span></span></p>
<p><em>&nbsp;for(var a=1;i&lt;10;i++)<br />{<br />&nbsp;ctx.save();<br />&nbsp;ctx.translate(a,a);<br />&nbsp;drawSomething();<br />&nbsp;ctx.restore();<br />}</em></p>
<p><span class="long_text" lang="it"><span>Nel caso di&nbsp; IE9 nelle animazioni&nbsp;di immagini, il ridisegno delle stesse sfrutta le capacit&agrave; della GPU e consente di ottenere delle per eccellenti, sfruttando intervalli di ridisegno che consentono di ottenere un elevatissimo numero di frame al secondo con una eccellente esperienza utente ed un ottima fluidit&agrave; nelle animazioni. Un bel esempio di animazioni lo trovate nel <a target="_blank" href="http://ie.microsoft.com/TEStdrive/">Test Drive Center </a>&nbsp;come ad esempio l'applicazione <a target="_blank" href="http://ie.microsoft.com/TEStdrive/Performance/FishIETank/Default.html">fishIETank</a> e <a target="_blank" href="http://ie.microsoft.com/TEStdrive/Performance/Galactic/Default.html">Galactic</a> . Anche nel gi&agrave; citato <a target="_blank" href="http://ie.microsoft.com/TEStdrive/Graphics/CanvasPad/Default.html">Canvas Pad</a> trovate un esempio di animazione utile per approfondire l'utilizzo del canvas per questo tipo di operazione.</span></span></p>
<p><span class="long_text" lang="it"><span><span title="Click for alternate translations" class="hps">Una delle</span> <span title="Click for alternate translations" class="hps">fasi</span> <span title="Click for alternate translations" class="hps">dell'animazione</span> <span title="Click for alternate translations" class="hps">&egrave; quello di</span> <span title="Click for alternate translations" class="hps">rendere</span> <span title="Click for alternate translations" class="hps">una immagine</span> <span title="Click for alternate translations" class="hps atn">(</span><span title="Click for alternate translations">o</span> <span title="Click for alternate translations" class="hps">una cella</span> <span title="Click for alternate translations" class="hps">singola animazione</span><span title="Click for alternate translations">)</span> <span title="Click for alternate translations" class="hps">nella</span> <span title="Click for alternate translations" class="hps">posizione</span> <span title="Click for alternate translations" class="hps">specifica</span> <span title="Click for alternate translations" class="hps">e ci sono</span> <span title="Click for alternate translations" class="hps">due</span> <span title="Click for alternate translations" class="hps">principali tecniche</span> <span title="Click for alternate translations" class="hps">di</span> <span title="Click for alternate translations" class="hps">calcolo della</span> <span title="Click for alternate translations" class="hps">posizione specifica.</span> <span title="Click for alternate translations" class="hps">Queste</span> <span title="Click for alternate translations" class="hps">tecniche di</span> <span title="Click for alternate translations" class="hps">animazione</span> <span title="Click for alternate translations" class="hps">sono</span><span title="Click for alternate translations">:</span><br /><span title="Click for alternate translations" class="hps">- Animazione</span> <span title="Click for alternate translations" class="hps">frame</span><span title="Click for alternate translations">-based</span><br /><span title="Click for alternate translations" class="hps">- Animazioni</span> <span title="Click for alternate translations" class="hps">time-based&nbsp;</span><br /><br /><span title="Click for alternate translations" class="hps">Nell'</span><span title="Click for alternate translations" class="hps">animazione</span> <span title="Click for alternate translations" class="hps">frame</span><span title="Click for alternate translations">-based</span> <span title="Click for alternate translations" class="hps">oggetti</span> <span title="Click for alternate translations" class="hps">vengono spostati</span> <span title="Click for alternate translations" class="hps">lo stesso numero</span> <span title="Click for alternate translations" class="hps">di</span> <span title="Click for alternate translations" class="hps">pixel</span> <span title="Click for alternate translations" class="hps">in</span> <span title="Click for alternate translations" class="hps">ogni aggiornamento.</span> <span title="Click for alternate translations" class="hps">Nelle</span>&nbsp;time-based lo spostamento &egrave;&nbsp;<span title="Click for alternate translations" class="hps">basato sul tempo e</span>&nbsp;<span title="Click for alternate translations" class="hps">vengono spostati</span> <span title="Click for alternate translations" class="hps">lo stesso numero</span> <span title="Click for alternate translations" class="hps">di</span> <span title="Click for alternate translations" class="hps">pixel per</span> <span title="Click for alternate translations" class="hps">unit&agrave;</span> <span title="Click for alternate translations" class="hps">di</span> <span title="Click for alternate translations" class="hps">tempo</span><span title="Click for alternate translations">. Ognuno dei due approcci ha vantaggi e svantaggi ed &egrave; pi&ugrave; idoneo in determinati scenari.&nbsp;</span></span></span></p>
<p><span class="long_text" lang="it"><span><span title="Click for alternate translations">&nbsp;L'animazione frame-based&nbsp;<span title="Click for alternate translations" class="hps">&egrave; semplice da</span> <span title="Click for alternate translations" class="hps">implementare</span> <span title="Click for alternate translations" class="hps">ma &egrave; fortemente&nbsp;dipendente dalla velocit&agrave; del PC cos&igrave; come lo spazio percorso dall'animazione non &egrave; costante e per tanto questo tipo di tecnica &egrave; poco usata nei giochi e di pi&ugrave; per animazioni che non hanno dei percorsi di dimensione predefinita in una specifica unit&agrave; di tempo. Di seguito un semplice esempio di frame-base animation, dove ctx &egrave; il context 2d del canvas,&nbsp;che in questo caso cancella completamente il canvas perch&egrave; abbiamo un unico oggetto presente nell'animazione:</span></span></span></span></p>
<p><span class="long_text" lang="it"><span><span title="Click for alternate translations"><span title="Click for alternate translations" class="hps"><em>var distance=5 lastFrameTime = 0;<br />setInterval(drawTimeBased, 16);</em></span></span></span></span></p>
<p><span class="long_text" lang="it"><span><span title="Click for alternate translations"><span title="Click for alternate translations" class="hps"><em>function drawFrameBased() {</em></span></span></span></span></p>
<p><span class="long_text" lang="it"><span><span title="Click for alternate translations"><span title="Click for alternate translations" class="hps"><em>y1 += distance; </em></span></span></span></span></p>
<p><em><span class="long_text" lang="it"><span><span title="Click for alternate translations"><span title="Click for alternate translations" class="hps">ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);<br />ctx.drawImage(img, x1, y1, imgWidth, imgHeight);<br />}<br /></span></span></span></span><span class="long_text" lang="it"><span><span title="Click for alternate translations"></span></span></span></em></p>
<p><span class="long_text" lang="it"><span><span title="Click for alternate translations"></span></span></span></p>
<p><span class="long_text" lang="it"><span></span></span></p>
<p><span class="long_text" lang="it"><span></span></span></p>
<p>Di seguito abbiamo un esempio di questo&nbsp;tipo di animazione &nbsp;applicata ad un canvas sovrapposto ad un video, che illustra la flessibilit&agrave; con cui il canvas pu&ograve; essere usato anche per gestire animazioni in overlay ad un video, come ad esempio banner pubblicitari o altri elementi interattivi:</p>
<p><em>&nbsp;&lt;!DOCTYPE html&gt;<br />&lt;html&gt;<br />&lt;head&gt;</em></p>
<p><em>&lt;/head&gt;<br />&lt;body&gt;</em></p>
<p><em>&lt;video id="myVideo" src="fish.mp4"&nbsp; height="480" width="640"autoplay controls loop&gt;<br />&nbsp;Video is not supported.<br />&lt;/video&gt;</em></p>
<p><em>&lt;canvas id="myCanvas"&nbsp; height="480" width="640" style="left: 0px; top: 0px; position: absolute;" &gt;<br />&nbsp;Canvas is not supported<br />&lt;/canvas&gt;<br />&lt;script language="javascript"&gt;<br />&nbsp;&nbsp;&nbsp; window.addEventListener("load", Main, false);<br />&nbsp;&nbsp;&nbsp; var y1 = 10, distance = 1;<br />&nbsp;&nbsp;&nbsp; var customText = "Canvas text on top of video";<br />&nbsp;&nbsp;&nbsp; var ctx;<br />&nbsp;&nbsp;&nbsp; var msg;<br />&nbsp;&nbsp;&nbsp; function Main() {</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msg = document.getElementById("msg");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myCanvas = document.getElementById("myCanvas");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (myCanvas.getContext) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx = myCanvas.getContext("2d");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.shadowOffsetX = 5;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.shadowOffsetY = 5;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.shadowBlur = 5;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.shadowColor = "grey";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.fillStyle = "black";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.font = '35px "Segoe UI" bold';</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setInterval(draw, 16);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</em></p>
<p><em>&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; function draw() {</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (distance &lt; 0) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; distance = 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; y1 += distance;</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // make text show up again when it falls of the page<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (y1 &gt; (ctx.canvas.height - 35)) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; y1 = 10;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.fillText(customText, 60, y1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; }&nbsp;</em></p>
<p><em>&lt;/script&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;</em></p>
<p class="gt-icon-c" tabindex="0" role="button" id="gt-res-listen"><span lang="it" id="result_box"><span title="Click for alternate translations" class="hps">L'Animazione</span> <span title="Click for alternate translations" class="hps">time-based </span><span title="Click for alternate translations" class="hps">&egrave;&nbsp;</span><span title="Click for alternate translations" class="hps">pi&ugrave; complicata</span> <span title="Click for alternate translations" class="hps">da implementare.</span> <span title="Click for alternate translations" class="hps">In questo</span> <span title="Click for alternate translations" class="hps">tipo di</span> <span title="Click for alternate translations" class="hps">animazione</span> la <span title="Click for alternate translations" class="hps">distanza</span> <span title="Click for alternate translations" class="hps">per spostare</span> <span title="Click for alternate translations" class="hps">una specifica immagine</span> <span title="Click for alternate translations" class="hps">&egrave;</span> <span title="Click for alternate translations" class="hps">calcolato su</span> l'<span title="Click for alternate translations" class="hps">unit&agrave; di</span> <span title="Click for alternate translations" class="hps">tempo.</span> <span title="Click for alternate translations" class="hps">Questo tipo</span> <span title="Click for alternate translations" class="hps">di</span> <span title="Click for alternate translations" class="hps">animazione</span> <span title="Click for alternate translations" class="hps">non</span> <span title="Click for alternate translations" class="hps">&egrave;</span> <span title="Click for alternate translations" class="hps">dipendente</span> <span title="Click for alternate translations" class="hps">della macchina</span> <span title="Click for alternate translations" class="hps">e pu&ograve;</span> <span title="Click for alternate translations" class="hps">essere usata</span> <span title="Click for alternate translations" class="hps">nei giochi</span><span title="Click for alternate translations">.</span> <span title="Click for alternate translations" class="hps">Nei giochi in genere&nbsp;</span><span title="Click for alternate translations" class="hps">tutti i giocatori</span> <span title="Click for alternate translations" class="hps">hanno</span> <span title="Click for alternate translations" class="hps">la stessa quantit&agrave; di</span> <span title="Click for alternate translations" class="hps">tempo</span> <span title="Click for alternate translations" class="hps">da spendere per</span> <span title="Click for alternate translations" class="hps">il</span> <span title="Click for alternate translations" class="hps">certo livello</span><span title="Click for alternate translations">,</span> <span title="Click for alternate translations" class="hps">a prescindere</span> <span title="Click for alternate translations" class="hps">macchina</span> <span title="Click for alternate translations" class="hps">utilizzata</span> <span title="Click for alternate translations" class="hps">per</span> <span title="Click for alternate translations" class="hps">giocare</span> <span title="Click for alternate translations" class="hps">una partita</span> <span title="Click for alternate translations" class="hps">-</span> <span title="Click for alternate translations" class="hps">quindi</span> <span title="Click for alternate translations" class="hps">abbiamo</span> <span title="Click for alternate translations" class="hps">bisogno di</span> <span title="Click for alternate translations" class="hps">animazione</span> <span title="Click for alternate translations" class="hps">indipendente</span> <span title="Click for alternate translations" class="hps">macchina</span><span title="Click for alternate translations">. La fluidit&agrave; dell'animazione &egrave; dipendente dalle performance del PC su cui si esegue ma le distanze sono costanti nell'unit&agrave; di tempo.&nbsp;Ecco di seguito un esempio di codice di utilizzo di un'animazione time-based:</span></span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span lang="it"><span title="Click for alternate translations"><em>var speed = 250, lastFrameTime = 0;<br />setInterval(drawTimeBased, 16);</em></span></span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span lang="it"><span title="Click for alternate translations"><em>function drawTimeBased() {<br />// time since last frame<br />var now = new Date().getTime();<br />dt = (now - lastFrameTime) / 1000;<br />lastFrameTime = now;</em></span></span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span lang="it"><span title="Click for alternate translations"><em>y2 += speed * dt;</em></span></span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span lang="it"><span title="Click for alternate translations"><em>ctx.clearRect(x2, 0, ctx.canvas.width, ctx.canvas.height);<br />ctx.drawImage(img, x2, y2, imgWidth, imgHeight);<br />}<br /></em></span></span></p>
<p><span lang="it"><span title="Click for alternate translations"></span></span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span title="Click for alternate translations" class="hps">In questo caso l'oggetto&nbsp;non viene spostato di una distanza predeterminata ad ogni intervallo di ridisegno dell'animazione, ma viene i</span><span title="Click for alternate translations" class="hps">nvece calcolato lo spostamento, in base al</span>&nbsp;<span title="Click for alternate translations" class="hps">tempo</span> <span title="Click for alternate translations" class="hps">trascorso</span> <span title="Click for alternate translations" class="hps">dal</span> <span title="Click for alternate translations" class="hps">precedente</span> <span title="Click for alternate translations" class="hps">ciclo</span> <span title="Click for alternate translations" class="hps">di rendering</span><span title="Click for alternate translations">.</span> <br /><span title="Click for alternate translations" class="hps">Ricordando&nbsp;che</span> <span title="Click for alternate translations" class="hps">la distanza</span> <span title="Click for alternate translations" class="hps">&egrave;</span> <span title="Click for alternate translations" class="hps">uguale</span> <span title="Click for alternate translations" class="hps">velocit&agrave;</span> <span title="Click for alternate translations" class="hps">moltiplicata per</span> <span title="Click for alternate translations" class="hps">il tempo, che l</span><span title="Click for alternate translations" class="hps">a velocit&agrave; &egrave;</span> <span title="Click for alternate translations" class="hps">una costante</span> <span title="Click for alternate translations" class="hps">che</span> <span title="Click for alternate translations" class="hps">abbiamo</span> <span title="Click for alternate translations" class="hps">fissato</span> <span title="Click for alternate translations" class="hps">da qualche parte</span> <span title="Click for alternate translations" class="hps">nel</span> <span title="Click for alternate translations" class="hps">codice</span> <span title="Click for alternate translations" class="hps atn">(</span><span title="Click for alternate translations">250</span> <span title="Click for alternate translations" class="hps">pixel</span> <span title="Click for alternate translations" class="hps">nel nostro caso</span><span title="Click for alternate translations">)</span><span title="Click for alternate translations">, e che </span>&nbsp;<span title="Click for alternate translations" class="hps">dt</span> <span title="Click for alternate translations" class="hps">&egrave; calcolato</span> <span title="Click for alternate translations" class="hps">in</span> <span title="Click for alternate translations" class="hps">ciascun</span> <span title="Click for alternate translations" class="hps">ciclo</span><span title="Click for alternate translations">, </span><span title="Click for alternate translations" class="hps">possiamo</span> <span title="Click for alternate translations" class="hps">facilmente</span> <span title="Click for alternate translations" class="hps">calcolare</span> <span title="Click for alternate translations" class="hps">la distanza</span> <span title="Click for alternate translations" class="hps">necessaria per</span> <span title="Click for alternate translations" class="hps">muovere</span> <span title="Click for alternate translations" class="hps">il nostro</span> <span title="Click for alternate translations" class="hps">oggetto</span> in ogni step dell'animazione<span title="Click for alternate translations">.</span> <span title="Click for alternate translations" class="hps">Tutto quello che dobbiamo</span> fare &egrave; <span title="Click for alternate translations" class="hps">moltiplicare</span> <span title="Click for alternate translations" class="hps">la velocit&agrave;</span> per <span title="Click for alternate translations" class="hps">il delta del </span><span title="Click for alternate translations" class="hps">tempo, ottenendo i pixel da applicare al movimento</span><span title="Click for alternate translations">. </span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span title="Click for alternate translations"></span><span title="Click for alternate translations">Di seguito un semplice esempio delle due tipologie di animazione applicate sullo stesso canvas a coordinate differenti:</span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span title="Click for alternate translations"><em>&lt;!DOCTYPE html&gt;</em></span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span title="Click for alternate translations"><em>&lt;html lang="en"&gt;</em></span></p>
<p><span title="Click for alternate translations"></span></p>
<p>&nbsp;<em>&lt;head&gt;<br />&lt;title title="test anim"&gt;&lt;/title&gt;<br />&lt;meta charset="utf-8" /&gt;</em></p>
<p class="gt-icon-c" tabindex="0" role="button"><em>&nbsp;&lt;script language="javascript" type="text/javascript"&gt; &nbsp;<br />&nbsp;&nbsp;var myCanvas, ctx;<br />&nbsp;&nbsp;var x1=10,y1=10,x2=200,y2=10, distance=5, speed = 250;<br />&nbsp;&nbsp;var img;<br />&nbsp;&nbsp;var imgWidth;<br />&nbsp;&nbsp;var imgHeight;<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;var lastFrameTime = 0;&nbsp;&nbsp;</em></p>
<p class="gt-icon-c" tabindex="0" role="button"><em>&nbsp;&nbsp;window.addEventListener("load", Main, false); <br />&nbsp;&nbsp;<br />&nbsp;&nbsp;function Main(){<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;myCanvas = document.getElementById("myCanvas");<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;if (myCanvas.getContext) {<br />&nbsp;&nbsp;&nbsp;&nbsp;ctx = myCanvas.getContext("2d");<br />&nbsp;&nbsp;&nbsp;&nbsp;img = new Image();<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;img.addEventListener("load", function(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;imgWidth = 100;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;imgHeight = 100;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lastFrameTime = new Date().getTime();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setInterval(draw, 16);<br />&nbsp;&nbsp;&nbsp;&nbsp;}, false);<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;img.src = "IELogo.png";<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;function draw() {<br />&nbsp;&nbsp;&nbsp;drawFrameBased();<br />&nbsp;&nbsp;&nbsp;drawTimeBased();<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<br />&nbsp;&nbsp;function drawFrameBased() {<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;y1 += distance; <br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;// make image show up again when it falls of the page<br />&nbsp;&nbsp;&nbsp;if (y1 &gt; (ctx.canvas.height - imgHeight)) {<br />&nbsp;&nbsp;&nbsp;&nbsp;y1 = 10;<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);<br />&nbsp;&nbsp;&nbsp;ctx.fillText("Frame Based Animation", x1, 10);<br />&nbsp;&nbsp;&nbsp;ctx.drawImage(img, x1, y1, imgWidth, imgHeight);<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;}<br />&nbsp;<br />&nbsp;&nbsp;function drawTimeBased() {<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;// time since last frame<br />&nbsp;&nbsp;&nbsp;var now = new Date().getTime();&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;dt = (now - lastFrameTime) / 1000;<br />&nbsp;&nbsp;&nbsp;lastFrameTime = now;<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;y2 += speed * dt;<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;// make image show up again when it falls of the page&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;if (y2 &gt; (ctx.canvas.height - imgHeight)) {<br />&nbsp;&nbsp;&nbsp;&nbsp;y2 = 10;<br />&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;ctx.clearRect(x2, 0, ctx.canvas.width-(x1+imgWidth), ctx.canvas.height);<br />&nbsp;&nbsp;&nbsp;ctx.fillText("Time Based Animation", x2, 10);<br />&nbsp;&nbsp;&nbsp;ctx.drawImage(img, x2, y2, imgWidth, imgHeight);&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;}</em></p>
<p class="gt-icon-c" tabindex="0" role="button"><em>&nbsp;&lt;/script&gt; <br />&lt;/head&gt;<br />&lt;body&gt;<br />&lt;canvas id="myCanvas" width="500" height="500"&gt;<br />&nbsp;Canvas is not supported.<br />&lt;/canvas&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;<br /></em></p>
<p class="gt-icon-c" tabindex="0" role="button">&nbsp;Come potete vedere nell'esempio precedente le due animazioni vengono eseguite assieme ed in questo caso, viene cancellato prima del ridisegno solo la porzione del canvas che contiene la posizione dell'elemento su cui si esegue l'animazione, utilizzando il metododo del context <em>clearRect</em>&nbsp; utilizzando come parametri&nbsp;le specifiche coodinate e dimensioni<em>.</em></p>
<p>
<p class="gt-icon-c" tabindex="0" role="button"><span title="Click for alternate translations">Nel caso di animazioni complesse con elementi che durante il movimento , simulano anche altri tipi di movimento&nbsp;come ad esempio l'applicazione <a target="_blank" href="http://ie.microsoft.com/TEStdrive/Performance/FishIETank/Default.html">FishIETank</a> che simula un acquario con i pesci che si muovono&nbsp;nello spazio e che cambiano direzione e muovono la coda per simulare il nuoto:</span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span title="Click for alternate translations"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/2287.schermo1.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-67/2287.schermo1.PNG" border="0" /></span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span title="Click for alternate translations">o come il bellissimo esempio\gioco implementato in HTML5 <a s_oidt="0" s_oid="http://www.pirateslovedaisies.com/" href="http://www.pirateslovedaisies.com/"><span style="color: #ca491d;">Pirates Love Daises</span></a>&nbsp;:</span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span title="Click for alternate translations"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/8686.pirate.JPG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-67/8686.pirate.JPG" border="0" /></span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span title="Click for alternate translations"></span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span title="Click for alternate translations">Dove ci sono vari personaggi animati su canvas.</span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span title="Click for alternate translations">Per gestire &nbsp;animazioni di questo tipo e garantire le migliori performance possibili, sfruttando in particolare su IE9 l'accelerazione grafica, si utilizzano genericamente delle tecniche&nbsp; ( <a target="_blank" href="http://en.wikipedia.org/wiki/Sprite_(computer_graphics)">sprite animation</a> ) che accorpano in un unica immagine gli stati degli elementi durante le animazioni, che vengono suddivisi in celle con delle specifiche coordinate, utilizzate poi nelle funzioni che ridisegnano gli oggetti.</span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span title="Click for alternate translations">&nbsp;Ad esempio nel caso dell'acquario del <a target="_blank" href="http://ie.microsoft.com/TEStdrive/Performance/FishIETank/Default.html">FishIETank</a>&nbsp; abbiamo, una immagine di background che viene applicata al canvas e una immagine in cui sono contenuti tutti gli stati necessari all'animazione dei pesci e le diverse "razze" di pesci che vengono poi divise in celle che permettono attraverso le coordinate definite di ridisegnare una specifica cella sul canvas:</span></p>
<p class="gt-icon-c" tabindex="0" role="button"><span title="Click for alternate translations"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/61/67/7607.fish.JPG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-61-67/7607.fish.JPG" border="0" />&nbsp;&nbsp;&nbsp;</span><br />&nbsp;</p>
<p class="gt-icon-c" tabindex="0" role="button">&nbsp;Di seguito un esempio della funzione che sintetizza l'utilizzo delle immagini all'interno&nbsp;dell'animazione:</p>
<p class="gt-icon-c" tabindex="0" role="button"><em>&lt;img id="imageStrip" src="fishstrip.png" style="display: none" tabIndex="-1"&gt; </em></p>
<p class="gt-icon-c" tabindex="0" role="button"><em>//&nbsp;rif allo&nbsp;strip di img<br />imageStrip = document.getElementById('imageStrip');</em></p>
<p class="gt-icon-c" tabindex="0" role="button"><em>ctx.drawImage (</em></p>
<p class="gt-icon-c" tabindex="0" role="button"><em>// informazioni source image </em></p>
<p class="gt-icon-c" tabindex="0" role="button"><em>FishImageStrip, // source<br />fishW * cell, // sX&nbsp;della cella<br />fishH * species, // SY&nbsp; della cella<br />fishW, // larghezza della cella<br />fishH, // altezza della cella</em></p>
<p class="gt-icon-c" tabindex="0" role="button"><em>// Canvas destinazione<br />x, // X dove&nbsp;disegnare il pesce<br />y, // Y dove&nbsp;disegnare il pesce<br />fishW, // larghezza&nbsp;<br />fishH, // altezza&nbsp;<br />);<br /></em></p>
<p class="gt-icon-c" tabindex="0" role="button">&nbsp;Come si vede nel codice precedente, viene caricata l'intera immagine &egrave; poi utilizzate le coordinate della cella per indicare la porzione di immagine (cella) da disegnare nel canvas di destinazione ad una specifica coordinata, con delle dimensioni definite.</p>
<p>&nbsp;Il particolare nell'applicazione FishIETank dell'acquario viene essenzialmente:</p>
<p>1-<span title="Click for alternate translations" class="hps">Caricato ed impostato lo sfondo dell'acquario</span></p>
<p><span title="Click for alternate translations" class="hps">2- </span><span title="Click for alternate translations" class="hps">caricata l'intera </span><span title="Click for alternate translations" class="hps">sprite</span>&nbsp;image</p>
<p>3- applicare al canvas le trasformazioni per disegnare il pesce, salvando prima lo stato del canvas, per riapplicarlo ripetendo poi le operazioni per ogni pesce </p>
<p><span title="Click for alternate translations" class="hps">Questa demo di acquario, utilizza una animazione Time-Based. </span><span title="Click for alternate translations" class="hps">Di seguito un esempio semplificato della funzione di disegno dei pesci:</span></p>
<p><span title="Click for alternate translations" class="hps"><em>var myCanvas = document.getElementById('myCanvas');<br />var ctx = myCanvas.getContext("2d");<br />&hellip;<br />ctx.save();<br />ctx.translate(x, y);<br />ctx.scale(scale, scale); <br />ctx.transform(flip, 0, 0, 1, 0, 0);<br />ctx.drawImage(imageStrip, fishW * cell, fishH * species, fishW, fishH, -fishW / 2, -fishH / 2, fishW, fishH);<br />scale = nextScale;<br />ctx.restore();<br /></em></span></p>
<p><span title="Click for alternate translations" class="hps"><span lang="it" id="result_box"><span title="Click for alternate translations" class="hps">Proprio</span> <span title="Click for alternate translations" class="hps">come</span> <span title="Click for alternate translations" class="hps">ho</span> <span title="Click for alternate translations" class="hps">spiegato</span> prima, viene salvato lo stato&nbsp;del canvas<span title="Click for alternate translations">,</span> <span title="Click for alternate translations" class="hps">applicata la trasformazione e disegnata la cella corretta in base allo stato dell'animazione e</span><span title="Click for alternate translations" class="hps">&nbsp;quindi</span> <span title="Click for alternate translations" class="hps">ripristinato</span> <span title="Click for alternate translations" class="hps">lo stato.</span>&nbsp;Viene applicata anche una&nbsp;<span title="Click for alternate translations" class="hps">trasformazione personalizzata</span>&nbsp;<span title="Click for alternate translations" class="hps">dove&nbsp;</span>&nbsp;i<span title="Click for alternate translations" class="hps">l</span> <span title="Click for alternate translations" class="hps">primo parametro</span> <span title="Click for alternate translations" class="hps atn">(</span><span title="Click for alternate translations">flip</span><span title="Click for alternate translations">)</span> <span title="Click for alternate translations" class="hps">&egrave; 1</span> <span title="Click for alternate translations" class="hps">o</span> <span title="Click for alternate translations" class="hps">-1&nbsp;serve per eventualmente&nbsp;riflettere</span> <span title="Click for alternate translations" class="hps">pesce</span> <span title="Click for alternate translations" class="hps">in</span> <span title="Click for alternate translations" class="hps">una direzione diversa in base alla direzione che il pesce ha nell'acquario. Le </span><span title="Click for alternate translations" class="hps">trasformazioni nel canvas in IE9 vengono svolte sfruttando completamente&nbsp;</span><span title="Click for alternate translations" class="hps">la</span> <span title="Click for alternate translations" class="hps">GPU con&nbsp; l'accelerazione grafica offerta dal browser, garantendo delle perfomance eccellenti nell'animazione</span><span title="Click for alternate translations">.</span></span></span></p>
</p>
<p><span title="Click for alternate translations" class="hps"><span lang="it"><span title="Click for alternate translations">Approfondendo il funzionamento dell'applicazione nel test drive di IE9,&nbsp;trovate&nbsp;&nbsp;di seguito una porzione del codice della applicazione <a target="_blank" href="http://ie.microsoft.com/TEStdrive/Performance/FishIETank/Default.html">fishIETank</a> che potete anche trovare online&nbsp;&nbsp; :</span></span></span></p>
<p>
<p><span title="Click for alternate translations" class="hps"><span lang="it"><span title="Click for alternate translations"><em>//set up the canvas<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var tempCtx = document.createElement("canvas");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tempCtx.id = "canvas1";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tempCtx.setAttribute('width', WIDTH);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tempCtx.setAttribute('height', HEIGHT);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tempCtx.setAttribute('tabIndex', -1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.body.insertBefore(tempCtx, document.body.firstChild);</em></span></span></span></p>
<p><span title="Click for alternate translations" class="hps"><span lang="it"><span title="Click for alternate translations"><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var tempCtx3 = document.createElement("canvas");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tempCtx3.id = "background";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tempCtx3.setAttribute('width', WIDTH);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tempCtx3.setAttribute('height', HEIGHT);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tempCtx3.setAttribute('tabIndex', -1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.body.insertBefore(tempCtx3, document.body.firstChild);</em></span></span></span></p>
<p><span title="Click for alternate translations" class="hps"><span lang="it"><span title="Click for alternate translations"><em></em></span></span></span></p>
<p><span title="Click for alternate translations" class="hps"><span lang="it"><span title="Click for alternate translations"><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx = tempCtx.getContext("2d");</em></span></span></span><span title="Click for alternate translations" class="hps"><span lang="it"><span title="Click for alternate translations"><span lang="IT"><span style="font-size: x-small;"></span></span></span></span></span>
<p><span title="Click for alternate translations" class="hps"><span lang="it"><span title="Click for alternate translations"><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx3 = tempCtx3.getContext("2d");</em></span></span></span></p>
<p><span title="Click for alternate translations" class="hps"><span lang="it"><span title="Click for alternate translations"><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //draw the background<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; backgroundImage = document.getElementById('backgroundImage');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drawBackground();</em></span></span></span></p>
<p><span title="Click for alternate translations" class="hps"><span lang="it"><span title="Click for alternate translations"><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //create the fish<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; imageStrip = document.getElementById('imageStrip');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; createFish(startFish);</em></span></span></span></p>
<p><span title="Click for alternate translations" class="hps"><span lang="it"><span title="Click for alternate translations"><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //start animation<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setInterval(function () { draw(); }, 16);<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; window.addEventListener("resize", OnWindowResize, false);</em></span></span></span></p>
<p><span title="Click for alternate translations" class="hps"><span lang="it"><span title="Click for alternate translations"></span></span></span></p>
<p><span title="Click for alternate translations" class="hps"><span lang="it"><span title="Click for alternate translations"></span></span></span></p>
<p id="gt-res-dict">Vengono creati i canvas utilizzati nella parte grafica, impostato il background dell'acquario e creati gli oggetti che rappresentano i pesci ed avviato l'intervallo che chiama la funzione che si occupa di ridisegnare l'acquario e implementare quindi le animazioni. La funzione draw essenzialmente effettua un ciclo nella collezione di oggetti che rappresentano i pesci, creati nella funzione createFish&nbsp;e che consarvano lo stato in cui si trovano all'interno dell'acquario e chiama il metodo swim, che fa essenzialmente ridisegnare l'acquario:</p>
<p><em>function draw() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //clear the canvas<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.clearRect(0, 0, WIDTH, HEIGHT);</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //set velocity of fish as a function of FPS<br />&nbsp;&nbsp;&nbsp;var fps = fpsMeter.meterFps;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; power = Math.min(fps, 60);<br />&nbsp;&nbsp;&nbsp;if(isNaN(power)) power = 1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //velocity = 100 + 100 * (power * power / 3600); //exponential curve between 100-200<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; velocity = Math.floor((power * power * .5) / 3) &lt; 1 ? 1 : Math.floor((power * power * .5) / 3);&nbsp; //exponential curve between 1 and 600.</em></p>
<p><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Draw each fish<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (var fishie in fish) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fish[fishie].swim();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; </em></p>
<p><em>&nbsp;&nbsp;&nbsp;//draw fpsometer with the current number of fish&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fpsMeter.Draw(fish.length);&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</em></p>
<p>&nbsp;</p>
<p>la funzione swim, essenzialmente ridisegna il pesce dopo aver calcolato le coordinate della posizione del pesce. Il cuore nella funzione lo vedete di seguito:</p>
<p><em>//draw the fish<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //locate the fish<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.save();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.translate(x, y);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.scale(scale, scale); // make the fish bigger or smaller depending on how far away it is.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.transform(flip, 0, 0, 1, 0, 0); //make the fish face the way he's swimming.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.drawImage(imageStrip, fishW * cell, fishH * species, fishW, fishH, -fishW / 2, -fishH / 2, fishW, fishH); //draw the fish<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.save();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scale = nextScale // increment scale for next time <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.restore();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.restore();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //increment to next state<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x = nextX;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; y = nextY;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; z = nextZ;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (cell &gt;= cellCount-1 || cell &lt;= 0) { cellReverse = cellReverse * -1; } //go through each cell in the animation<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cell = cell + 1 * cellReverse; //go back down once we hit the end of the animation<br /></em></p>
<p>Che come descritto prima, essenzialmente salva il contesto del canvas, posiziona e disegna il pesce e ripristina lo stato e incrementa le variabili per il successivo ridisegno. Nella demo <a target="_blank" href="http://ie.microsoft.com/TEStdrive/Performance/FishIETank/Default.html">FishIETank</a> potete vedere ed apporfondire il resto dell'esempio di animazione con il canvas realizzata.</p>
</p>
</p>]]></content:encoded>
    </item>
  </channel>
</rss>