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

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

Follow

Get every new post delivered to your Inbox.