MCI(Multimedia Control Interface) : là bộ thư viện cung cấp các ứng dụng độc lập với thiết bị trong máy tính, sử dụng cho việc điều khiển âm thanh và các thiết bị ngoại vi
Trang 1MCI Báo cáo tìm hiểu
Chương 1: Giới thiệu về MCI
1.1 Định nghĩa MCI:
MCI(Multimedia Control Interface) : là bộ thư viện cung cấp các ứng dụng
độc lập với thiết bị trong máy tính, sử dụng cho việc điều khiển âm thanh và
các thiết bị ngoại vi
1.2 Tính năng:
- Cho phép ứng dụng điều khiển các file audio/video và các thiết bị ngoại
vi một cách độc lập
- Điều khiển và hổ trợ các thiết bị về multimedia bao gồm :
waveform-audio divice, MIDI sequencers, CD waveform-audio devices, and digital-video (video
playback) devices
- Trong Windows, các MCI drivers phổ biến sẽ được tích hợp sẵn
- Mỗi thiết bị multimedia mới, như một sound card hay một video card,
sẽ có MCI drivers đi kèm để điều khiển nó
1.3 Sử dụng:
- MCI hỗ trợ 2 phương pháp lập trình:
+ Command string (mciSendString) + Command message (mciSendCommand)
Có thể sử dụng một trong 2 hoặc là cả 2 phương pháp trên trong chương
trình MCI
Qui trình xử lý chung của MCI :
Chương 2: Giới thiệu về command string và command messages
1.1 Command string:
- Điều khiển thiết bị Multi-Media bằng câu lệnh ở dạng chuỗi
- Sử dụng hàm mciSendString để gửi chuỗi đến các thiết bị MCI,
hàm mciSendString được định nghĩa trong thư viện: <Winmm.lib>
- Hệ thống chuyển các command strings thành các command
messages trước khi gửi chúng cho các thiết bị MCI xử lí chúng
- Các câu lệnh có cùng cấu trúc(ngoại trừ thao tác Open) tổng quát,
bắt đầu từ các từ khóa: open, play, stop….
+ Định dạng : command device_id argument
Trong đó:
Command: từ khóa định rõ thao tác cần thực hiện, bắt đầu
từ những từ: open, play, stop…
Xử lý, điều khiển Đóng thiết bị
Mở thiết bị
Trang 2Device_id: ID của thiết bị được mở( Tạo ra khi thiết bị được mở)
Argument : cờ và giá trị được sử dụng cho command
Ví dụ: hàm gửi lệnh play với cờ from và to
+ Giới hạn: Không hỗ trợ xử lý các file có dấu cách, file có dấu nháy kép(“) thì phải dùng cặp nháy kép kẹp nó
DWORD PlayFromTo(LPSTR lpstrAlias, DWORD dwFrom, DWORD dwTo)
{
char achCommandBuff[128];
// Form the command string.
wsprintf(achCommandBuff, "play %s from %u to %u",
lpstrAlias, dwFrom, dwTo);
// Send the command string.
return mciSendString(achCommandBuff, NULL, 0, NULL);
}
-Giải nghĩa lệnh mciSendString:
MCIERROR mciSendString(
LPCTSTR lpszCommand,
LPTSTR lpszReturnString,
UINT cchReturn,
HANDLE hwndCallback
Trang 3+ lpszCommand: Chuỗi câu lệnh gởi tới các thiết bị multimedia để yêu cầu thực hiện các thao tác: close, play, stop…( có cấu trúc được nêu trên)
+ lpszReturnString: là con trỏ trỏ tới chuỗi chứa thông tin trả về từ thiết bị media (có thể bằng NULL nếu ta không quan tâm đến thông tin phản hồi)
+ cchReturn: Độ dài tính theo số kí tự của lpszReturnString + hwndCallback: Handle của cửa sổ để xử lí các message do thiết
bị multimedia gởi mỗi khi có sự kiện nào đó (như chơi hết file, đóng file,
…)
• Tham số này chỉ có ý nghĩa khi trong câu lệnh gởi tới thiết bị
có chứa cờ notify
• Message được gởi là MM_MCINOTIFY
• Có thể bằng NULL nếu không quan tâm đến việc nhận message phản hồi
+ Giá trị trả về sẽ là 0 nếu thành công và nếu thất bại thì sẽ trả về low-older word của DWORD chứa lỗi trả về Nếu lỗi trả về là của thiết bị thì hight-older word của giá trị trả về là thiết bị, nếu không thì sẽ bằng 0 MCIERROR là của MCI định nghĩa sẵn để bắt các lỗi trả về
+ Ví dụ về các bước mở file tới đóng file âm thanh
• Đầu tiên là mở thiết bị( bước đầu trong 3 bước(hình 1)):
char szMCIString[128];
char szDevType[30];
char szFileName[128];
MCIERROR dwReturn;
strcpy(szFileName,"C:/Windows/Windows_Start.wav");
strcpy(szDevType, "waveaudio");
sprintf(szMCIString, "open %s type %s alias MyWAV",
szFileName, szDevType);
dwReturn = mciSendString(szMCIString, NULL, 0, NULL);
Mở file có đường dẫn là: “C:/Windows/Windows_Start.wav”
Trang 4“waveaudio” để xác định loại thiết bị, tham khảo bảng sau:
Digital-video playback Digitalvideo
Video-cassete recorder Vcr
Hoặc muốn xác định với file có đuôi nào thì chọn loại thiết bị nào có thể xem tại: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\MCI Extensions
• Tiếp theo là xử lý điều khiển( bước 2 trong hình 1):
Play:
mciSendString("play MyWAV notify", NULL, 0, m_hWnd);
Pause:
mciSendString("stop MyWAV", NULL, 0, NULL);
• Bước cuối cùng là đóng thiết bị(bước 3 trong hình 1):
mciSendString("close MyWAV", NULL, 0, NULL);
NHẬN XÉT:
+ Ưu điểm: Câu lệnh bằng ngôn ngữ tự nhiên, dễ hiểu
+ Khuyết điểm: Giới hạn nêu trên
1.2 Command Messages:
Điều khiển các thiết bị Multi-Media bằng cách sử dụng các thông điệp (message)
Mỗi lệnh điều khiển tương ứng với 1 message khác nhau
Message được gởi đến thiết bị thông qua hàm mciSendCommand
được định nghĩa trong thư viện <Winmm.lib>
Viết theo kiểu cấu trúc, các cấu trúc này đã được định nghĩa sẵn
Ví dụ: 3 bước xử lý file âm thanh
• Mở thiết bị
MCI_OPEN_PARMS mciOpenParams;
mciOpenParams.lpstrDeviceType = " mpegvideo ";
mciOpenParams.lpstrElementName = “C:/MySound.mp3”;
DWORD mciError = mciSendCommand(NULL, MCI_OPEN,
Trang 5MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,
(DWORD)(LPVOID) &mciOpenParams);
mciDevID = mciOpenParams.wDeviceID;
Các tham số cũng giống như ở sendString
Sau khi thực hiện xong lệnh mciSendCommand thì sẽ trả về thiết bị được
mở, sẽ lưu lại trong mciOpenParams.wdeviceID
Về lệnh mciSendCommand:
MCIERROR mciSendCommand(
MCIDEVICEID IDDevice,
UINT uMsg,
DWORD fdwCommand,
DWORD_PTR dwParam
);
+ IDDevice: ID của thiết bị, có thể bằng NULL nếu thực hiện MCI_OPEN +uMsg: liệt kê các kiểu thông dụng dùng cho mp3 và một số file âm thanh khác:
đó
nhạc
+ dwParam: Trỏ tới struct của tham số tương ứng
• Điều khiển, xử lý thiết bị Play một bài nhạc:
MCI_PLAY_PARMS mciPlayParms;
Trang 6mciPlayParms.dwCallback = NULL;
mciSendCommand(mciDevID,MCI_PLAY,MCI_NOTIFY, (DWORD_PTR)&mciPlayParms);
Pause lại:
MCI_GENERIC_PARMS mciGenericParms;
mciGenericParms.dwCallback = NULL;
mciSendCommand(mciDevID,MCI_PAUSE,MCI_NOTIFY,
(DWORD_PTR)&mciGenericParms);
SEEK tới thời điểm nào đó:
MCI_SEEK_PARMS mciSeekParms;
mciSeekParms.dwCallback = NULL;
mciSeekParms.dwTo = 20000;
mciSendCommand(mciDevID,MCI_SEEK,MCI_WAIT|MCI_TO,
(DWORD) (LPMCI_SEEK_PARMS) &mciSeekParms);
Trước khi seek thì phải pause bài nhạc trước, sau khi seek phải play lại bài nhạc mới có thể nghe được tại thời điểm seek tới
• Đóng thiết bị
mciSendCommand(mciDevID,MCI_CLOSE,0,NULL);
Chương 3: Thao khảo toàn diện về MCI
PHUC********mất cả buổi sáng và tối đó mày************
có mấy cái bỏ vì đọc ko hỉu.
Classifications of MCI Commands
MCI định nghĩa 4 loại command:
• System commands được điều khiển trực tiếp bởi MCI nhiều hơn bởi driver.
• Required commands được điều khiển bởi driver Tất cả MCI driver phải hỗ trợ các
required command và các cờ hiệu (flags).
• Basic commands (còn gọi là optional commands) được dùng bởi một số thiết bị Nếu
một thiết bị có hỗ trợ một basic command, nó phải hỗ trợ một tập các cờ đã được định nghĩa cho command đó.
• Extended commands dùng riêng cho device type hay driver.
Trong khi system command và required command là các tiểu command để thiết lập cho MCI driver, thì basic command và extended command lại không được hỗ trợ bởi tất cả các driver Ứng dụng của bạn có thể sử dụng system command, required command và các cờ của chúng,
Trang 7nhưng nếu nó cần dùng một basic command, extended command hay flag, thì đầu tiên nó cần truy vấn driver bằng cách sử dụng capability ( MCI_GETDEVCAPS ) command.
System Commands
break MCI_BREAK set một break key cho một MCI device.
sysinfo MCI_SYSINFO trả về thông tin của các MCI device.
Required Commands
Tất cả MCI device đều hỗ trợ các required command sau:
capability MCI_GETDEVCAPS lấy được chức năng của device.
info MCI_INFO lấy được thông tin văn bản về device.
status MCI_STATUS lấy thông tin về tình trạng của device.
Basic Commands
load MCI_LOAD tải dữ liệu từ 1 tập tin.
pause MCI_PAUSE dừng việc playing Việc phát hay ghi lại có thể được nối lại tại vị trí hiện hành. play MCI_PLAY bắt đầu truyền dữ liệu đầu ra.
record MCI_RECORD bắt đầu ghi dữ liệu đầu vào.
resume MCI_RESUME nối lại việc phát hoặc ghi trên 1 thiết bị tạm dừng( paused device).
save MCI_SAVE lưu dữ liệu xuống tập tin trên đĩa.
seek MCI_SEEK nhảy tới hay lui.
set MCI_SET thiết lập tình trạng hoạt động của device.
status MCI STATUS lấy thông tin tình trạng của device.
stop MCI_STOP dừng việc playing.
Nếu một driver hỗ trợ một basic command, thì nó cũng phải hỗ trợ một tập chuẩn các cờ hiệu cho command.
Extended Commands
configure MCI_CONFIGURE digitalvideo hiển thị hộp thoại cấu hình.
cue MCI_CUE digitalvideo, waveaudio chuẩn bị cho việc ghi hay phát.
delete MCI_DELETE waveaudio xóa một segment dữ liệu từ tập tin media.
escape MCI_ESCAPE videodisc gửi thông tin tùy chỉnh(custom information)đến thiết bị.
freeze MCI_FREEZE overlay disable sự tiếp nhận video đến bộ đệm
frame
put MCI PUT digitalvideo, overlay xác định nguồn, đích và khung cửa sổ.
setaudio MCI_ SETAUDIO digitalvideo set các tham số audio cho video.
Trang 8setvideo MCI_ SETVIDEO digitalvideo set các tham số video.
signal MCI_SIGNAL digitalvideo xác định vị trí quy định với một tín hiệu
unfreeze MCI_UNFREEZE overlay cho phép vùng đệm frame thu dữ liệu video.
update MCI_UPDATE digitalvideo vẽ lại khung hiện tại vào device context
where MCI WHERE digitalvideo, overlay lấy được hình chữ nhật xác định nguồn, đích đến, hoặc diện tích khung. window MCI_WINDOW digitalvideo, overlay điều khiển sự hiển thị cửa sổ.
///// mới thêm vào chiều này
Phụ thêm: Playing a movie
Đối với file movie, cụ thể là file avi thì khi mở lên vào điều khiển ta cần phải handle được cửa sổ mới xuất hiện ra để chứa cái hình ảnh hiển thị movie Có thể là một cửa sổ mới hiện ra hay là nằm vào luôn trong cửa sổ hiện hành là tùy vào người lập trình chọn lựa Chúng ta có thể làm điều đó bằng cách:
Đầu tiên chúng ta sẽ mở file avi, set lại cửa sổ cha và tạo ra một cửa sổ con mới:
MCI_DGV_OPEN_PARMS mciOpen;
mciOpen.lpstrElementName = lpstrFile; // đường dẫn file.
mciOpen.dwStyle = WS_CHILD; // style của cửa sổ
mciOpen.hWndParent = hWnd; // set cửa sổ cha
if (mciSendCommand(0, MCI_OPEN,
(DWORD)(MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_DGV_OPEN),
(DWORD)(LPSTR)&mciOpen) == 0)
{
// Open operation is successful Continue
}
Trang 9Khi một cửa sổ mới tạo ra thì kích cỡ của cửa sổ này phù hợp với kích cỡ của file avi Vì thế ta phải có một bước là điều chỉnh kích cỡ của cửa sổ mới tạo ra cho đúng kích thước của file avi
HWND hwnd;
MCI_DGV_RECT_PARMS mciRect;
// Lấy kích cỡ của AVI với tham số MCI_WHERE, kết quả sẽ trả về cho // mciRect
mciSendCommand(wDeviceID, MCI_WHERE, MCI_DGV_WHERE_SOURCE,
(DWORD)(LPSTR)&mciRect);
// Create the playback window Make it bigger for the border
// Note that the right and bottom members of RECT structures in MCI // are unusual; rc.right is set to the rectangle's width, and
// rc.bottom is set to the rectangle's height.
hwndMovie = CreateWindow("mywindow", "Playback",
WS_CHILD|WS_BORDER, 0,0,
mciRect.rc.right+(2*GetSystemMetric(SM_CXBORDER)),
mciRect.rc.bottom+(2*GetSystemMetric(SM_CYBORDER)),
hwndParent, hInstApp, NULL);
if (hwndMovie){
Trang 10// Window created OK; make it the playback window
MCI_DGV_WINDOW_PARMS mciWindow;
mciWindow.hWnd = hwndMovie;
mciSendCommand(wDeviceID, MCI_WINDOW, MCI_DGV_WINDOW_HWND,
(DWORD)(LPSTR)&mciWindow);
}
Chú ý rằng là dòng màu đỏ trong CreateWindow là 2 tham số chỉ chiều rộng và chiều cao của cửa sổ chứa file avi, điều này có nghĩa là 2 tham số đó cũng chính là chiều dài và chiều rộng của file avi
Việc tạo ra cửa sổ, handle cửa sổ đó và điều chỉnh kích thước đã được thực hiện rồi thì việc cuối cùng chỉ là gửi lệnh MCI_PLAY đến cho thiết bị, và file avi
sẽ được mở nhờ vào MCIAVI driver
DWORD PlayMovie(WORD wDevID, DWORD dwFrom, DWORD dwTo)
{
MCI_DGV_PLAY_PARMS mciPlay; // play parameters
DWORD dwFlags = 0;
// Check dwFrom If it is != 0 then set parameters and flags
if (dwFrom){
mciPlay.dwFrom = dwFrom; // set parameter
dwFlags |= MCI_FROM; // set flag to validate member }
Trang 11// Check dwTo If it is != 0 then set parameters and flags
if (dwTo){
mciPlay.dwTo = dwTo; // set parameter
dwFlags |= MCI_TO; // set flag to validate member }
// Send the MCI_PLAY command and return the result
return mciSendCommand(wDevID, MCI_PLAY, dwFlags,
(DWORD)(LPVOID)&mciPlay);
}
Cách lấy thông tin của file movie:
Các file âm thanh thì format là thời gian, còn file movie thì sẽ có format là FRAME Vì thế, để lấy thông tin các file movie thì ta phải chọn lại format từ TIME thành FRAME
MCI_DGV_SET_PARMS mciSet;
// Put in frame mode
mciSet.dwTimeFormat = MCI_FORMAT_FRAMES;
mciSendCommand(wDeviceID, MCI_SET,
MCI_SET_TIME_FORMAT,
(DWORD)(LPSTR)&mciSet);
Trang 12Để làm việc đó thì ta sử dụng cấu trúc MCI_DGV_SET_PARMS và gửi lệnh với tham số MCI_SET
Ví dụ nhỏ về truy xuất thông tin của file movie: Ta muốn lấy vị trí hiện hành của file movie đang play: ( dĩ nhiên là ta phải set format là FRAME trước)
MCI_DGV_STATUS_PARMS mciStatus;
mciStatus.dwItem = MCI_STATUS_MODE;
mciSendCommand(wDeviceID, MCI_STATUS,
MCI_STATUS_ITEM,
(DWORD)(LPSTR)&mciStatus);
// Nếu đang PLAY thì lấy thời điểm hiện hành
if (mciStatus.dwReturn == MCI_MODE_PLAY)
{
mciStatus.dwItem = MCI_STATUS_POSITION;
mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)(LPSTR)&mciStatus);
// Giá trị trả về sẽ gán vào mciStatus.dwReturn
}
Phụ thêm trên là những gì rất căn bản để Play Movie Dĩ nhiên khi code sẽ phải
xử lý nhiều việc hơn như seek,phóng to, thu nhỏ…