4. CHƯƠNG 4: XÂY DỰNG ỨNG DỤNG STREAM AUDIO VÀ VIDEO
4.1.1 Định dạng hỗ trợ Audio
Android hỗ trợ nhiều định dạng file audio và giải mã (codecs for playback) tuy nhiên nó chỉ hỗ trợ vài định dạng recording .
AAC: Advanced Audio Coding codec là những định dạng như .m4a hoặc 3.gp. AAC là một chuẩn được sử dụng bở Ipod và các thiết bị chơi nhạc khác. Android hỗ trợ định dạng audio là MPEG-4 files và 3GP files
MP3: MPEG-1 Audio Layer 3, .mp3 file. MP3, đây là dạng được dùng phổ biến nhất được hỗ trợ trong Android cho phép đọc những file online trên nhiều web sites và music stores
AMR: Adaptive Multi-Rate codec những định dạng như .3gp hoặc .amr . AMR là chuẩn được sử dụng trong truyền thông và những ứng dụng voice calling trên điện thoại và được hỗ trợ phát triển bởi nhà sản xuất.
Ogg: Ogg Vorbis, .ogg files. Là một dạng mã nguồn mở, chất lượng của nó cũng giống như định dạng MP3 và ACC.
PCM:Pluse Code Modulation thông thường là những file .wav. PCM là công nghệ sử dụng cho lưu trữ trên máy tính và thiết bị digital audio khác 4.1.2 Khởi chạy Audio thông qua Intent
Chúng ta sẽ xây dựng một ứng dụng Music đơn giản, có thể chạy tất cả các files mà Android hỗ trợ. Đơn giản ta chỉ cần gọi chương trình có sẵn trong hệ điều hành và sử dụng nó. Đầu tiên ta thiết lập giao diện cho ứng dụng là như sau:
55
Hình: 1Play audio layout
Trong Activity chính thiết lập sự kiện cho nút button
Khi button được nhấn sự kiện onClick sẽ xảy ra, trong hàm này ta sẽ gọi App có sẵn để chạy file .Định danh ACTION_VIEW để gọi đến app có sẵn .Tạo đối tượng sdcard để lấy đường dẫn các file trong sdcard sau đó lấy đường dẫn đến file cần mở .Đối với đối tượng intent ta sử dụng phương thức để cài đặt đường dẫn Uri và kiểu định dạng cho nó và cuối cùng kích hoạt Intent.
Trong file manifest ta phải khai báo để cho phép Activity gọi App khác
playButton = (Button) this.findViewById(R.id.Button01);
playButton.setOnClickListener(this);
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
File sdcard = Environment.getExternalStorageDirectory();
File audioFile =new File (sdcard.getPath()+
"/music/goodmorningandroid.mp3");
intent.setDataAndType(Uri.fromFile(audioFile), "audio/mp3"); startActivity(intent);
56
Quan sát Emulator ta có kết quả :
Hình: 2Kết quả chạy audio
4.1.3 Xây dựng một ứng dụng Audio
Dĩ nhiên là ta có thể tự xây dụng một ứng dụng audio riêng, tạo giao diện theo ý thích và lựa chọn các tính năng cần thiết cho ứng dụng. Để làm được điều này, Android cung cấp một class là MediaPlayer. Class này được sử dụng cho playback và điều khiển cho cả audio và video. Ví dụ đơn giản nhất về MediaPlayer là chạy một file audio được đóng gói trong chính ứng dụng. Ta phải tạo một folder tài nguyên tên là raw như sau :
57
Tạo một đối tượng MediaPlayer sử dụng phương thức create của class MediaPlayer với tham số truyền vào là đường dãn tới thư mục chứa file cần mở :
Sau đó sử dụng phương thức start để mở :
Control playback
Class MediaPlayer chứa nhiều class để bắt sự kiện mà MediaPlayer gửi tới.Nó sẽ gọi phương thức onCompletionListener và được cài đặt thông qua phương thức setOnCompletionListener khi mà file audio được chạy xong.
Sau đây em xin trình bày một ví dụ về tạo giao diện điều khiển đơn giản để chạy một file audio được đóng gói sẵn trong ứng dụng.
Tạo giao diện điều khiển như sau :
Hình: 4Layout audio custom
mediaPlayer = MediaPlayer.create(this, R.raw.goodmorningandroid);
58
Sử dụng hàm findViewById , ta truy cập đến đối tượng nút nhấn được định nghĩa trong file Layout XML
Để activity có thể đáp ứng được sự kiện click, ta phải khai báo bộ listener cho 2 nút này :
Tạo một đối tượng theView và khai báo sự kiện chạm tay vào màn hình:
Dưới đây là phương thức onComletion, được gọi khi MediaPlayer hoàn tất việc chạy file audio. Ta sẽ gọi phương thức start để chạy audio sau đó gọi phương thức seekTo đến vị trí đã lưu vào biến position :
Khi người dùng chạm vào màn hình cảm ứng , phương thức onTouch sẽ được gọi. Trong phương thức này chúng ta chỉ quan tâm đến sự kiện ACTION_MOVE, đây là sự kiện khi người dùng chạm và di chuyển ngón tay trên màn hình.
stopButton = (Button) this.findViewById(R.id.StopButton);
startButton.setOnClickListener(this);
stopButton.setOnClickListener(this);
theView = this.findViewById(R.id.theview);
theView.setOnTouchListener(this);
mediaPlayer.start();
@Override
public boolean onTouch(View v, MotionEvent me) {
if (me.getAction() == MotionEvent.ACTION_MOVE) {
if (mediaPlayer.isPlaying()) {
position = (int) (me.getX() *
mediaPlayer.getDuration() / theView
.getWidth());
Log.v("SEEK", "" + position);
59
Cuối cùng, thiết lập sự kiện nút nhấn cho 2 Button :
4.2 Background and Networked Audio 4.2.1 Background Audio Playback 4.2.1 Background Audio Playback
Nếu chúng ta muốn người dùng có thể làm những công việc khác trong khi đang nghe nhạc ? Có một vấn đề gặp phải khi nó được xây dựng bằng activities. Hệ điều hành Android sẽ có thể kill activities khi nó không tương tác với người dùng. Nếu OS kill 1 activity đang chạy audio, thì điều này sẽ gây nên sự bất tiện cho người dùng. Một giải pháp được đưa ra là thay vì sử dụng activities ta sẽ sử dụng Service.
Service
Để chắc chắn rằng audio sẽ tiếp tục được chạy khi ứng dụng không còn tương tác với người dùng nữa ta cần tạo một Service. Đó là một thành phần của các ứng dụng Android mà các tác vụ được chạy ngầm và không tương tác và hiển thị với người dùng.
Có 2 class Service khác nhau được dùng trong Android. Thứ nhất là Local Service. Local Service tồn tại như một phần ứng dụng đặc biệt và được truy cập chỉ bởi ứng dụng đó.Loại thứ 2 là Remote Service. Chúng có thể giao tiếp được với nhau có thể được truy cập và điểu khiển bởi ứng dụng khác
Điều khiển một MediaPlayer trong Service
Để cho phép điều khiển một đối tượng MediaPlayer ta cần phải ràng buộc Activity và Service với nhau. Một khi hoàn tất thì Activity và Service sẽ cùng chạy song song với nhau
4.2.2 Networked Audio
Trong Android có hỗ trợ khá nhiều để chạy nhiều định dạng file audio có sẵn trên network
@Override
public void onClick(View v) {
if (v == stopButton) {
mediaPlayer.pause();
60
61
HTTP audio playback
Ta sẽ xây dựng một ví dụ đơn giản để chạy audio file và truy cập thông qua
HTTP, server có sẵn :
http://www.mobvcasting.com/android/audio/goodmorningandroid.mp3
Trong phương thức onCreate() tạo mới một đối tượng mediaplayer:
Với đối tượng này sử dụng phương thức SetDataSource() để link đến file cần
chạy trên server, sau đó là phương thức prepare() nó sẽ load dữ liệu từ server về máy, chú ý là nó sẽ load toàn bộ file về máy trước khi thực hiện start().Sau đó file này sẽ được chạy như ví dụ trước đã trình bày. Các phương thức này có thể ném ra các ngoại lệ nên phải dùng cú pháp try catch :
Audio playback HTTP sử dụng prepareAsync()
Trong ví dụ trước, chỉ chạy được những file có dung lượng nhỏ, còn đối với những file có dung lượng lớn thì thời gian load toàn bộ file về rất lớn, không đáp ứng được nhu cầu chạy trực tuyến . Một giải pháp để khắc phục điều này là sử dụng phương thức prepareAsync(). Phương thức này sẽ load dữ liệu vào một buffer và khi đầy thì sẽ chuyển vào trạng thái prepared như trong sơ đồ Hình 4.5.
Dưới đây ta sẽ phân tích đoạn code để hiện thực hóa sơ đồ trên : Tạo giao diện layout như sau:
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource("http://www.mobvcasting.com/android/audio
/goodmorningandroid.mp3");
mediaPlayer.prepare();
62
Hình: 6Layout audio HTTP
Trong phương thức onCreate ta khai báo và thiết lập các đối tượng cần thiết:
Nút nhấn, textView, MediaPlayer…
Thiết lập bộ listener cho từng đối tượng:
Gọi phương thức :
stopButton.setOnClickListener(this);
startButton.setOnClickListener(this);
stopButton.setEnabled(false);
startButton.setEnabled(false);
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setDataSource("http://www.mobvcasting.com/android/audio
63
Xử lí các sự kiện. Khi có nút nhấn tương ứng, ta hiển thị lên màn hình phương thức nào đã được gọi
Trong file manifest phải khai báo quyền sử dụng Internet :
Streaming Audio via HTTP
Phương thức streaming thông qua HTTP được phát triển từ năm 1999 do một công ty tên là Nullsoft, Công ty này xây dựng một phần mềm gọi là WinAMP một trình chơi MP3 thông dụng, và phát triển 1 server hỗ trợ audio streaming sử dụng HTTP. Hiện tại một số lượng lớn các servers và phần mềm playback được tạo ra đều hỗ trợ giao thức ICY, và là một chuẩn cho việc nghe radio online.
Ví dụ về sử dụng và chạy 1 file M3U chứa đường dẫn đến một trạm radio hoặc bất kì M3U file chứa URL thích hợp:
Tạo layout như sau : @Override
public void onClick(View v) {
if (v == stopButton) {
mediaPlayer.pause();
statusTextView.setText("pause called");
startButton.setEnabled(true);
}else if (v == startButton) {
mediaPlayer.start();
statusTextView.setText("start called");
startButton.setEnabled(false);
stopButton.setEnabled(true);
} }
64
Trong phương thức onCreate để tạo các đối tượng sau :
Thiết lập các bộ Listener sự kiện cho các đối tượng:
Khi nút parseButton được nhấn, nó sẽ thực hiện phương thức
parsePlayListFile() mà chúng ta tự định nghĩa. Phương thức này tạo một đối tượng
HttpClient và gửi một yêu cầu đến server và ta sẽ nhân được một đối tượng trả về là HttpResponse. Tiến hành lấy nội dung từ đối tượng này bằng các câu lệnh sau :
parseButton = (Button) this.findViewById(R.id.ButtonParse);
playButton = (Button) this.findViewById(R.id.PlayButton);
stopButton = (Button) this.findViewById(R.id.StopButton);
editTextUrl =(EditText)this.findViewById(R.id.EditTextURL);
Hiển thị đường link lên màn hình edittext:
parseButton.setOnClickListener(this);
playButton.setOnClickListener(this);
stopButton.setOnClickListener(this);
mediaPlayer = new MediaPlayer();
InputStream inputStream = httpResponse.getEntity().getContent(); BufferedReader bufferedReader =new
65
Sử dụng phương thức readLine() cho đối tượng bufferedReader này ta sẽ thu
được dữ liệu dạng String. Nếu dữ liệu bắt đầu là kí tự # thì nó là metada và bỏ qua nó, ta chỉ quan tâm đến dữ liệu bắt đầu là http:// mà thôi, cứ mỗi khi lấy được 1 đường dẫn url ta lại add nó vào một đối tượng là playListItems. Như vậy quá trình phân tính file đã xong, ta cho phép nút nhấn playButton.
Khi người dùng nhấn playButton phương thức playPlaylistItems() được gọi. Phương thức này sẽ chạy đường dẫn đầu tiên trong đối tượng playListItems. Lấy đường dẫn lưu vào đối tượng path như sau:
Đến đây công việc còn lại đơn giản chỉ là tạo đối tượng MediaPlayer và sử dụng các phương thức để chạy giống như ví dụ trước đã để cập:
String path = ((PlaylistFile) playlistItems
66
4.3 Giới thiệu về Video playback 4.3.1 Định dạng hỗ trợ của Android 4.3.1 Định dạng hỗ trợ của Android
Thông thường định dạng mà Android hỗ trợ tương thích với nhiều loại thiết bị mobile. Nó hỗ trợ 3GP(.3gp) và MPEG-4(.mp4) . 3GP là chuẩn được dẫn xuất từ MPEG-4 được sử dụng cho mobile
Android hỗ trợ chuẩn mã hóa H.263 , được dùng cho ứng dụng video có bit rate thấp và độ trễ thấp
4.3.2 Cách mở một tập tin video lưu trữ trong SD card
Có nhiều cách để mở một tập tin có sẵn trong máy, em xin giới thiệu 3 cách như sau:
Ta có thể sử dụng Intent để khởi chạy một ứng dụng chạy video có sẵn của hệ điều hành
Sử dụng class VideoView và các phương thức setVideoUri() và start() .Add thêm các Widwet điều khiển bởi phương thức setMediaControler().
Sử dụng class MediaPlayer , cách này tương tự như đã trình bày ở phần audio. Cách này đem lại sự linh động cho người lập trình hơn tuy nhiên phải viết code dài và phức tạp
4.3.3 Network video
Có 2 phương pháp để xem video trên Internet thông dụng đó là downloading và streaming
Downloading :khi tải về một tập tin thì toàn bộ tập tin sẽ được lưu trên thiết bị, những tập tin này có thể mở và xem sau đó. Phương thức này có ưu điểm là truy xuất nhanh đến các đoạn khác nhau trong tập tin nhưng có một nhược điểm lớn là phải chờ cho toàn bộ tập tin được tải về trước khi nó có thể xem được. Nếu như tệp có dung lượng nhỏ thì điều này không có quá nhiều bất tiện, nhưng với tập tin lớn và nội dụng dài thì có thể gây ra nhiều khó chịu.
Streaming: Phương thức Streaming làm việc có một chút khác biệt- người dùng cuối có thể bắt đầu xem tập tin ngay khi nó bắt đầu được tải .Tập tin được gửi đến người dùng trong các chuỗi liên tiếp, và người dùng xem nội dung ngay khi nó đến mà không phải chờ đợi.
Streaming video là gửi nội dung ở dạng nén trên internet và hiển thị bởi người xem
ở thiết bị cuối theo thời gian thực. Hay nói một cách nôm na thì với streaming video hoặc streaming phương tiện truyền thông thì một người sử dụng tại thiết bị cuối không phải đợi để tải toàn bộ tập tin vềđểchạy nó. Thay vào đó các phương tiện truyền thông như video, tập tin nhạc được gửi theo một luồng dữliệu liên tục và được chạy ngay khi nó đến hoặc được lưu lại chờ đến lượt được chạy. Người
67
sử dụng sẽ cần một thiết bị mà nó được cài đặt sẵn chương trình phần mềm mà nó liên tục tải dữ liệu theo luồng về thiết bị rồi ngay sau đó kết nối đến màn hình hiển thị, loa… để chạy tập tin đó. Ngoài ra , Streaming video được thể hiện dưới hai dạng: Video theo yêu câu (on demand) và Video th ời gian thực (live event).
Video theo yêu cầu là các dữ liệu video được lưu trữ trên multimedia server và được truyền đến người dùng khi có yêu cầu, người dùng có toàn quyền để hiển thị cũng như thực hiện các thao tác (tua, dừng, nhẩy qua ..) với các đoạn dữ liệu này.
Video thời gian thực là các dữliệu video được chuyển trực tiếp từcác nguồn cung
cấp dữ liệu theo thời gian thực(máy camera, microphone, các thiết bị phát dữ liệu video ...). Các dữ liệu này sẽ được multimedia phát quảng bá thành các kênh người dùng sẽ chỉ có quyền truy nhập bất kỳ kênh ưa thích nào để hiển thị dữliệu mà không được thực hiện các thao tác tua, dừngvv.. trên các dữ liệu đó (giống như TV truyền thống).
Qui trình phát audio/video trực tuyến tiêu biểu bắt đầu với trang HTML trong trình
duyệt. Khi người dùng nhấn liên kết nội dung hoặc chương trình player, trình duyệt sẽ chuyển yêu cầu đến máy chủ web. Máy chủ web (web server) sẽchuyển yêu cầu đến máy chủ dành riêng cho việc truyền phát nội dung, máy chủ này được gọi là streaming server. Thực tế, có một số giải pháp sử dụng web server đảm nhận vai trò truyền phát audio/video (dùng giao thức http), giải pháp này ít tốn kém và đơn giản. Tuy nhiên, để cung cấp audio/video chất lượng cao cũng như khả năng đáp ứng đồng thời nhiều luồng truyền, cần có phần mềm máy chủ chuyên biệt (dùng giao thức truyền khác với máy chủ web).Ứng dụng phổ biến nhất của hình thức Streaming video là dịch vụvideo theo yêu
cầu. Khách hàng có thể yêu cầu phim video đã được số hóa (và nén mã hóa) lưu giữ tại server vào bất kỳ lúc nào. Nếu muốn, khách hàng có thể điều khiển luồng nội dung tạm dừng, quay lại hay tới (nhờgiao thức RTSP hay MMS); nói một cách khác, có thể thực hiện giống như với đầu máy tại nhà
4.3.4 Giao thức hỗ trợ HTTP và RTSP
HTTP : Chuẩn đầu tiên cần tìm hiểu là http. http được hỗ trợ một cách rộng rãi để truy cập mạng và không có vấn đề xảy ra với tường lửa hoặc giao thức streaming khác mà ta có. Media sử dụng HTTP là một chuẩn chung để xử lý dowload
Android cung cấp media theo yêu cầu với chuẩn MPEG-4 và 3GP file từ chuẩn web server thông qua HTTP .Có nhiều tools miễn phí và thương mại có sẵn để xử lý download với HTTP. Như là QuickTime X, Adobe Media Encoder, HanBrake, và VLC.
68
Tiếp theo, ta quan tâm đến tốc độ bit của video. GPRS có băng thông thấp hơn 20 kbps, và do đó audio và video sẽ được mã hóa với tốc độ đó. Thông thường khi dùng HTTP, media sẽ được buffered trên thiết bị , và playback sẽ được khởi chạy khi đã được tải đầy đủ và sẽ không gây ra vẫn đề pause khi đang chạy. Nếu đường truyền chỉ 20 kbps mà tốc độ encoded là 400 kbps thì trong mỗi giây của người dùng xem phải đợi download trong 20 giây. Nếu sử dụng wifi, 400 kbps có thể được đáp ứng
Thông thường tốc độ của mạng quyết định đến chất lượng của video.
RTSP :Chuẩn tiếp theo mà Android hỗ trợ là RTSP. RTSP là chuẩn cho Real Time Streaming Protocol Dạng media mà được hỗ trợ kèm theo RTSP trong Android là RTP (the Real time Transport Protocol), nhưng RTP chỉ hoạt động khi có RTSP. Giao thức khác với HTTP về quá trình download. Nó cần phải có một server đặc biệt để truyền video. Ví dụ ta có server có sẵn http://m.youtube.com
4.3.5 Giao thức hỗ trợ HTTP và RTSP 4.3.5.1 VideoView Network video player