Tạo Media Player trong Silverlight

Hồi tháng 8/2008, khi tôi bắt đầu tìm hiểu về Silverlight, đọc các bài báo giới thiệu về công nghệ này, tôi thấy nhiều bài đánh giá Silverlight mạnh nhất ở streaming video với nhiều định dạng khác nhau (đặc biệt là wmv của Microsoft), tôi đã có kế hoạch viết một một chương trình chơi video bằng Silverlight xem thực hư thế nào. Khi xây dựng chương trình, có khá nhiều vấn đề thú vị nảy sinh mà tôi đã giải quyết, mong muốn viết ra để chia sẻ với mọi người từ lâu nhưng giờ mới có thời gian ngồi viết entry này, mong muốn sẽ giúp được nhiều người (nhất là newbie đang tìm hiểu về silverlight)
Bạn có thể download source project tại đây, nhưng tôi khuyên với các bạn mới học thì nên làm theo các bước tôi trình bày bên dưới, tự mình làm sẽ nhớ lâu hơn mà

Xem Demo tại http://www.hoangleminh.com/www/Silverlight/MediaPlayer.html

Media Player

Phân tích các vấn đề cơ bản cần giải quyết thì một chương trình play video cơ bản cần phải có đó là :

  • Play/Pause/Stop (cái này đơn giản vì MediaElement của Silverlight hỗ trợ hết cá method này)
  • Thanh trượt Slider để ‘tua’ khi đang xem media và tự động slide khi video đang chạy
  • Thanh trượt để điều chỉnh volume
  • Hiển thị tổng thời gian và thời gian hiện tại
  • Fullscreen
  • Replay

Sau khi đã có một công cụ để chơi video cơ bản, việc xây dựng các hàm JavaScript tương tác với chương trình Silverlight cũng khá quan trọng

  • Tạo JavaScript API như function Play, Pause, SetSouceVideo, FullScreen…
  • Up chương trình lên web (vì hiện tại chưa có nhiều host hỗ trợ Framework 3.5 nên việc đưa một

chương trình Silverlight 2 lên web là khá khó khăn, tôi sẽ hướng dẫn cách dùng http://silverlight.live.com của Microsoft hỗ trợ cộng đồng lập trình Silverlight)  Tôi sẽ trình bày vấn đề này ở entry sau, không thì entry này dài quá
Công việc cần làm là vậy giờ bắt tay vào giải quyết thôi!!!

1. Play, Pause
Cái này đơn giản nhất giải quyết trước, sử dụng ToogleButton

MediaElement mePlayer;
ToogleButton btnPlay;
btnPlay.Checked += new RoutedEventHandler(btnPlay_Checked);
void btnPlay_Unchecked(object sender, RoutedEventArgs e)
{
mePlayer.Pause();
btnPlay.Content = "Play";
}
void btnPlay_Checked(object sender, RoutedEventArgs e)
{
mePlayer.Play();
btnPlay.Content = "Pause";
}

2. Slider (thanh trượt theo thời gian Play video)
2.1. Slider tự động chạy khi video đang chạy
Sử dụng đối tượng timer, khi MediaElement đang ở trạng thái play thì cứ 1s lại gọi method thay đổi vị trí của thumbs trên slider
CustomSlider sliderTime; //CustomSlider là Slider tự viết kế thừa từ Slider của Silverlight, sao lại có đối tượng này thì bạn theo dõi 2.2 sẽ rõ
TextBlock tbTime; //Hiển thị current time và tổng time của video
bool isSliderTimeLock = false;
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(50);
timer.Tick += new EventHandler(timer_Tick);
void mePlayer_CurrentStateChanged(object sender, RoutedEventArgs e)
{
if(mePlayer.CurrentState == MediaElementState.Playing)
{
timer.Start();
}
else
{
timer.Stop();
}
}

void timer_Tick(object sender, EventArgs e)
{
if((mePlayer.NaturalDuration.TimeSpan.TotalSeconds > 0) && (isSliderTimeLock == false))
{
tbTime.Text = string.Format("{0:00}:{1:00}", mePlayer.Position.Minutes, mePlayer.Position.Seconds);
sliderTime.Value = mePlayer.Position.TotalSeconds/mePlayer.NaturalDuration.TimeSpan.TotalSeconds;
}
}

2.2. Kéo chuột để chạy đến thời gian mong muốn
Cái này tưởng đơn giản nhưng làm tôi mất tới một tiếng để thực hiện, nguyên nhân là do một bug của Silverlight (từ Silverlight 2 beta 2, đến phiên bản Silverlight 2 tôi kiểm tra thấy vẫn còn, mặc dù đó là một bug đã được report và ghi nhận), số là thằng Slider có event là MouseLeftButtonUp và MouseLeftButtonDown đọc lên biết đoán ra ngay sự kiện này là gì, nhưng khổ nỗi dùng chuột kéo thả cái thumbs thì chả thấy gì cả
Cái này được tôi giải quyết bằng cách tạo CustomSlider kế thừa từ Silder và tự định nghĩa 2 sự kiện DragStarted và DragCompleted
public class CustomSlider:System.Windows.Controls.Slider
{
public CustomSlider():base()
{
DefaultStyleKey = typeof (CustomSlider);
}
public event EventHandler ThumbDragStarted;
public event EventHandler ThumbDragCompleted;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
//Set up drag event handlers
Thumb thumb = this.GetTemplateChild("HorizontalThumb") as Thumb; if (thumb != null)
{
thumb.DragStarted += new DragStartedEventHandler(thumb_DragStarted);
thumb.DragCompleted += new DragCompletedEventHandler(thumb_DragCompleted);
}
}
void thumb_DragCompleted(object sender, DragCompletedEventArgs e)
{
OnThumbDragCompleted(this, new EventArgs());
}
void thumb_DragStarted(object sender, DragStartedEventArgs e)
{
OnThumbDragStarted(this, new EventArgs());
}
public virtual void OnThumbDragStarted(object sender, EventArgs e)
{
if (ThumbDragStarted != null)
ThumbDragStarted(sender, e);
}
protected virtual void OnThumbDragCompleted(object sender, EventArgs e)
{
if (ThumbDragCompleted != null)
ThumbDragCompleted(sender, e);

}
}

Giờ tôi sẽ sử dụng cái CustomSlider này cho sliderTime (tua video) và sliderVolume (chỉnh volume)
void sliderTime_ThumbDragCompleted(object sender, EventArgs e)
{
isSliderTimeLock = false;
mePlayer.Position = TimeSpan.FromMilliseconds(mePlayer.NaturalDuration.TimeSpan.TotalMilliseconds * sliderTime.Value);
}

void sliderTime_ThumbDragStarted(object sender, EventArgs e)
{
isSliderTimeLock = true;
}
//Chỉnh volume
CustomeSlider sliderVolume;
void sliderVolume_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
{
mePlayer.Volume = sliderVolume.Value;
}

3. FullScreen
Sử dụng đối tượng System.Windows.Interop.SilverlightHost để thực hiện chức năng này
private System.Windows.Interop.SilverlightHost host;
Button btnFullScreen;
btnFullScreen.Click += new RoutedEventHandler(btnFullScreen_Click);
host.Content.FullScreenChanged += new EventHandler(Content_FullScreenChanged);

void btnFullScreen_Click(object sender, RoutedEventArgs e)
{
Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;
}

void Content_FullScreenChanged(object sender, EventArgs e)
{
if (host.Content.IsFullScreen)
{
userControl.Width = Application.Current.Host.Content.ActualWidth;
userControl.Height = Application.Current.Host.Content.ActualHeight;

mePlayer.Width = Application.Current.Host.Content.ActualWidth;
mePlayer.Height = Application.Current.Host.Content.ActualHeight;

}
else
{
userControl.Width = old_Width;
userControl.Height = old_Height;

mePlayer.Width = old_MediaWidth;
mePlayer.Height = old_MediaHeight;
}
}


Ta đã có một chương trình chơi media cơ bản, giờ xây dựng JavaScript API
4. JavaScript API
Theo tư duy thông thường thì ta phải tìm cách thế nào đó để JavaScript có thể chọc được vào trong ứng dụng Silverlight để gọi các function được định nghĩa bên trọng ứng dụng Silverlight
4.1. Lấy ra object Silverlight
Trong trang MediaPlayerTestPage.aspx:

Mã JavaScript để lấy ra object Silverlight nhúng trong trang web
function getSilverlightObject()
{
var pluginObject = $find(""); //Xaml1 chính là ID của đối tượng Silverlight được nhúng vào
var plugin = pluginObject.get_element();

return plugin

}

4.2. Đăng ký phương thức được phép gọi từ JavaScript
Giờ muốn sử dụng function nào trong đối tượng Silverlight thì ta phải đánh dấu đối tượng đó là [ScriptType] còn function được sử dụng là [ScriptMember], ví dụ ở đây ta muốn sử dụng function setSourceVideo() của đối tượng Page
[ScriptableType]
public partial class Page : UserControl
{
[ScriptableMember]
public void setSourceVideo(string url)
{
mePlayer.Source = new Uri(url, UriKind. RelativeOrAbsolute);
}
}

Trong mã JavaScript, muốn set lại source video ta chỉ cần gọi function setSouceVideo(string url) và truyền link video vào
function loadSource()
{
var pluginObject = $find("");
var plugin = pluginObject.get_element();
var url = “TestVideo.wmv”;
plugin.Content.mediaPlayer.setSourceVideo(url);
}

Xong, tương tự bạn có thể tự viết các JavaScript API như Play, Pause, Replay, Mute…

5. VisualStateManager
Trong project cũ viết trên Silverlight 2 beta 2 tôi có làm cả cái VisualStateManager thêm một số hiệu ứng di chuyển cho đẹp, nhưng khi update lên Silverlight 2 thì có nhiều thay đổi ở việc quản lý cái VisualState này nên tôi phải xóa hết đi, thế cũng tốt, đỡ rối mắt cho những người mới học, với ai muốn sourcecode của project có cả visual state này cho Silverlight 2 thì email cho tôi minh.hl86@gmail.com
Ở entry sau, tôi sẽ trình bày cách để đưa được một ứng dụng Silverlight 2 lên web và nhúng vào blog hay đâu đó và cả cách để treaming một video sử dụng dịch vụ miễn phí của Microsoft dành cho các nhà phát triển Silverlight http://silverlight.live.com

Lỗi Key Enter event của ASP.NET trên IE Browser với form có một textbox

Vừa deploy xong cái Social Graph dùng Javascript, đang rỗi việc lại nhớ đến blog lâu không viết gì, chợt nảy ra ý tưởng sẽ viết các entry về các vấn đề mà tôi đã gặp phải khi làm ở Vườn chim 2.0 và cách giải quyết, sau một thời gian sẽ có một danh sách dài các lỗi giời ơi đất hỡi, vừa giúp mình ghi nhớ, lại giúp cho những ai gặp phải những lỗi này có thể tham khảo cách giải quyết, cũng hay

Hôm nay sẽ bắt đầu với cái lỗi gặp phải khi tạo một form sử dụng ASP.NET, không fire ra event Key Enter trên Internet Explorer (cả IE6 và IE7, .NET Framework 1.0 hay 2.0 đều dính, chưa test trên 3.5)

Từ trước đến giờ thì việc submit một form trong ASP.NET là cực kỳ đơn giản rồi, nhập data xong Enter một phát là xong (ông nào thích chuột thì click lên button submit), mọi việc vẫn diễn ra nhưng kiểu đương nhiên nó phải thế, cho đến một hôm tôi phải tạo một cái form chỉ có 1 textbox và 1 button (làm cái form search ý mà), nhấn Enter xong, form vẫn submit nhưng event btnSubmit click thì chẳng thấy đâu (trêm IE thôi nhé, Firefox hay Opera hay là Chrome vẫn ngon). Search trên mạng thì cũng thấy nhiều chú dính, từ năm 2003 cũng có, cho đến 2008 vẫn có chú hỏi.

Nguyên nhân: thằng IE dở hơi khi form được submit đi có hơn 1 textbox thì HTTP_POST của nó thế này (or something like that)

TextBox1=Value1&TextBox2=Value2&...&TextBoxN=ValueN&btnSubmit=Click Me!

Nhưng nếu chỉ có 1 textbox thì nó lại không submit đi btnSubmit=ClickMe!, chỉ còn thế này

TextBox1=Value1

Thế nên nó không fire ra cái event btnSubmit click

Giải quyết:

Đơn giản chỉ là lừa nó, thêm vào một textbox và hidden nó đi, kiểu như này:

<asp:TextBox runat=”server” style=”visibility:hidden;display:none;” />

Một lỗi hết sức vớ vẩn nhưng cứ post lên, hi vọng giúp được ai đó

Nguồn tham khảo: http://www.aspdotnetfaq.com/Faq/Why-Button-Click-event-handler-code-is-not-executed-when-Enter-key-is-pressed-on-ASP-NET-Form.aspx

Còn khá nhiều lỗi vớ vẩn khác đã gặp phải, hi vọng sẽ có thời gian để post tiếp :) )

Phủ Lý city du hý nào!

Như đã rào đón một thời gian trước thì hôm nay xin chính thức thông báo là 3/11 tớ sẽ có một bà chị dâu. Để chào đón ngày trọng đại này, hôm nay – sau hơn nửa năm gác bút -  tớ viết cái entry nhắm lôi kéo các bạn về quê chơi cho vui, trước là mừng ngày vui của anh trai tớ, sau là cũng có dịp bạn bè lâu ngay gặp nhau, từ hồi đi làm đến giờ chẳng mấy khi có thời gian tụ tập đàn đúm

Với mục đích như trên thì tớ xin tạm phác ra đây kế hoạch ăn chơi nhảy múa ở Phủ Lý city

- Chiều thứ 7 (1/11) làm việc xong hẹn mọi người ở 15h ở cổng trường mình (địa điểm có thể xê dịch cho tiện, nhưng chắc cổng trường mình là tiện nhất), rồi phóng xe máy về nhà tớ (có 60km thôi, chậm thì mất 2 tiếng, tớ toàn đi tiếng rưỡi)

- Về nhà tớ chơi biết nhà +dọn dẹp (hehe) + … , rồi sau đó khả năng ra ngoài thuê nhà nghỉ cho sướng (nhà có các bác về), sẽ tài trợ một nửa chi phí ở (chắc là không nhiều lắm :) ) ). Tối sẽ đi lượn vài vòng Phủ Lý rồi đáp ở đâu thì tùy

- Sáng hôm sau dẫn đi ăn bánh cuốn chả đặc sản Phủ lý, đảm bảo ngon đừng hỏi, cho các chú thưởng ngoạn một vòng nữa rồi trưa về đánh chén

Phác qua qua thế vậy, ai có ý kiến gì vào comment nhé. Vì du hí vào cuối tuần nên mọi người cố gắng đi đông đủ nhé

Silverlight 2 Release Candidate

Mấy tuần nay bận làm cái WebProxy nên không cập nhật thông tin về Silverlight, hôm nay vào thấy thông báo Silverlight đã ra bản Release Candidate 0 từ hôm 25/9, thấy phấn chấn hẳn vì nghĩ là những bug từ bản beta2 mà dân tình than phiền suốt ngày sẽ được fix, nhưng đọc kỹ thì thấy cũng không có thay đổi nhiều, bug vẫn hoàn bug

Bản Silverlight RC0 này hiện tại chỉ dành cho Developer, chưa có bộ runtime dành cho End-User, nhóm phát triển của Microsoft tung ra bản này nhằm mục đích để cho các Dev có thời gian để nâng cấp project của mình từ beta1, beta2 lên RC0, để sắp tới Microsoft tung ra bộ cài Silverlight release là vừa. Như vậy là hiện tại các project build trên môi trường RC0 chưa thể deploy đến cho các end-user (làm gì đã có Runtime mà chạy)
Tham khảo thêm http://timheuer.com/blog/archive/2008/09/25/silveright-rc0-released-for-developers.aspx

Một số cải tiến nổi bật ở Silverlight RC0:
- Thêm 3 Controls mới:

  • PasswordBox: Hồi trước có thấy một ứng dụng bán hoa bằng Silverlight, phần đăng ký ô Password nhập vào ghi nguyên text, nhìn thương vật, giờ có cái này tốt rồi, có thể tạo Form Login ngon lành rồi
  • ProgressBar: cái này cũng quan trọng, viết ứng dụng upload khoai nhất khoản này, event UploadPrgressChanged của Class WebClient không fire, chả biết làm thế nào. Chưa Test nhưng đọc trên Forum của Silverlight.net thấy nói bản RC0 này vẫn chưa fix bug này
  • ComboBox: Cái này ra thì tốt nhưng cũng không mong đợi lắm vì dùng tạm cái ListBox cũng okie

- Hỗ trợ MessageBox.Show(): cái này hay, dễ kiểm soát giá trị khi code, trước muốn show ra value của đối tượng nào toàn phải kéo cái TextBlock vào
- Thêm một số Control hỗ trợ Skin: cái này nhìn mấy cái image minh họa thấy cũng chả khác mấy nên ko quan tâm, với cả cái này dành cho bọn designer nhiều hơn

Tham khảo thêm http://weblogs.asp.net/scottgu/archive/2008/09/25/silverlight-2-release-candidate-now-available.aspx

Còn một số ‘cải tiến’ nữa, nhưng chủ yếu là ở nhân bên trong như chuyển namespace hay kế thừa, bản chi tiết những thay đổi tôi up luôn đây để tiện cho tra cứu (dành cho người lười download bản doc về), cái này sẽ giúp ích cho những ai cần upgrade từ beta2 lên RC0, làm sao để project viết trên beta2 chạy ngon trên RC0 để mấy nữa Microsoft ra bản Release là vừa

Có một chú ý là enduser sẽ không được tự động nâng cấp lên phiên bản Silverlight Runtime mới khi cái này được release, trình duyệt sẽ chỉ notify người dùng nâng cấp lên thôi

Toàn bộ phần thay đổi của beta2 và RC0 được ghi bên dưới hoặc download tại đây
Đọc tiếp »

RIA – Tương lai của công nghệ Web

Các ứng dụng web mạnh cả về tính năng và giao diện người dùng được gọi với thuật ngữ RIA (Rich Internet Application, hay Rich Interactive Application với Microsoft).Hiện nay trên thị trường có ba đại gia đang tham cạnh trong nhau ở thị trường Web RIA là Adobe System với Flash/Flex, Microsoft với Silverlight và Sun với JavaFX, ở bài viết này sẽ chỉ đề cập đến Flex và Silverlight vì tính phổ biến và khả năng phát triển của nó trong tương lai

1 – Flex của Adobe

Hiện nay thì Adobe đang là bá chủ trong lĩnh vực RIA với quá trình phát triển bền vững lâu dài từ Shockwave, Flash rồi đến Flex (và tương lai gần sẽ là AIR). Với việc 95% máy tính trên thế giới được cài Adobe Flash Player thì Adobe có lợi thế rất lớn để triển khai các ứng dụng trên nền Flash/Flex. Flash là công nghệ thể hiện nổi tiếng về khả năng xử lý đồ họa vector và ảnh động, cho phép tạo nội dung đa phương tiện tương tác với người dùng thông qua ActionScript. Flex dựa trên Flash, dùng ngôn ngữ khai báo MXML dựa trên XML kết hợp với ActionScript, cung cấp sự tách biệt giữa phần giao diện người dùng và phần luận lý ứng dụng rõ ràng hơn so Flash.

Để phát triển các ứng dụng Flex có 3 cách, đơn giản nhất là sử dụng Dreamweaver CS3 viết mã HTML và JavaScript kết hợp với AIR SDK. Cách 2 là cài một add-ons cho Flash CS3 và cách thứ 3 là sử dụng Flex Builder 3 làm môi trường phát triển. Nếu bạn là người quan tâm đến công nghệ Flex thì tôi khuyên bạn nên bắt đầu với Flex Builder 3 vì tính kéo thả trực quan và dễ học của nó.

Bạn có thể tham khảo tính ‘RIA’ của các ứng dụng Flex tại đây: http://flex.org/showcase/

2 – Silverlight của Microsoft

Sinh sau để muộn hơn Flash/Flex rất nhiều nhưng Silverlight lại có lợi thế lớn vì là ‘con đẻ’ của Microsoft, mặc dù hiện tại thị phần còn khá khiêm tốn do không có nhiều máy tính được cài sẵn Silverlight runtime nhưng với tính phổ biến của hệ điều hành Windows và vũ khí Windows Update thì không khó để Microsoft có thể làm cho công nghệ Silverlight trở nên phổ biến.

Microsoft vốn nổi tiếng trong việc kế thừa ý tưởng của người đi trước (.NET là ví dụ điển hình của việc lấy ý tưởng từ Java của Sun), và Silverlight ra đời nhắm cạnh tranh với Adobe Flash/Flex cũng có khá nhiều cải tiến đáng kể, mà nổi bật là khả năng hỗ trợ mạnh mã về Multimedia truyền tài video chất lượng cao và hỗ trợ nhiều định dạng như .wmv, .avi… chứ không chỉ chơi các file .flv như Flash.

Đối với người sử dụng, chỉ cần cài silverlight runtime là có thể xem được các ứng dụng Silverlight trên hầu hết trình duyệt (IE, FireFox, Safari, Opera và thậm chỉ cả Chrome) và trên Hệ điều hành Windows hay Mac (đang phát triển trên Linux). Silverlight có giao diện được thiết kế dựa trên ngôn ngữ XAML và tương tác sử dụng javascript ( với Silverlight 1.0) hoặc C#, VB ( với Silverlight 2), do đó ta có thể sử dụng Visual Studio làm môi trường phát triển các ứng dụng Silverlight, rất gần gũi với các lập trình viên .NET. Cũng là một sinh viên Aptech và đang tìm hiểu về Silverlight nên tôi nghĩ đây là một công nghệ mới rất phù hợp và khá thú vị cho các bạn đã học qua năm thứ nhất tại Aptech. Để học Silverlight thì ta chỉ cần tìm hiểu thêm về ngôn ngữ đánh dấu hiển thị giao diện XAML, mà chủ yếu là kéo thả với công cụ Expression Blend.

Để xem công nghệ Silverlight đã hiện thực được các ứng dụng web RIA đến đâu, các bạn có thể tham khảo các showcase tại trang http://silverlight.net/Showcase/

Hoặc tham khảo ứng dụng PageTurn http://www.hoangleminh.com/Silverlight/Aptech

Hello world!

Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!