Deutsch

Воспоминание мультимедия 18.02.2025

2488  
uscheswoi_82 патриот18.02.25 15:06
18.02.25 15:06 

Всем привет! Хочу вспомнить про мультимедию. Будет от низкого уровня, до высокого уровня.

Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#1 
uscheswoi_82 патриот18.02.25 16:02
NEW 18.02.25 16:02 
в ответ uscheswoi_82 18.02.25 15:06

Будем сначало вспоминать на Си. на Embarcadero Dev-C++:

main.c:

#include <stdio.h>
#include <windows.h>

int main(int argc, char *argv[]) {
  /* Проигрывает аудиофайл с именем файла a_ja_pam_pam.wav синхронно,
     т.е. будет программа "висеть" пока не проиграет аудиофайл 
     a_ja_pam_pam.wav
  */
  sndPlaySound("a_ja_pam_pam.wav", SND_FILENAME | SND_SYNC); 
  return 0;
}

Но компилятор ошибку даст. Нужно добавить библиотеку libwinmm.a в проект, т.е. так: ../../Program Files (x86)/Embarcadero/Dev-Cpp/TDM-GCC-64/x86_64-w64-mingw32/lib/libwinmm.a

Теперь компилируем, и слышно как программа проигрывает аудиофайл a_ja_pam_pam.wav. После того как аудиофайл проиграет, наша программа завершается.

Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#2 
uscheswoi_82 патриот18.02.25 16:10
NEW 18.02.25 16:10 
в ответ uscheswoi_82 18.02.25 16:02

Если нужно чтобы проигралось ассинхронно, надо сделать вот так, вместо SND_SYNC заменим на SND_ASYNC:

main.c:

#include <stdio.h>
#include <windows.h>

int main(int argc, char *argv[]) {
  /* Проигрывает аудиофайл с именем файла a_ja_pam_pam.wav ассинхронно,
     т.е. будет программа "висеть" пока не проиграет аудиофайл 
     a_ja_pam_pam.wav
  */
  sndPlaySound("a_ja_pam_pam.wav", SND_FILENAME | SND_ASYNC);
  /* Специально нужна пауза, а то если выйдет из программы, звук перестанет проигрывать */
  system("pause");
  return 0;
}

Теперь запустив, слышим как проигрывается аудиофайл a_ja_pam_pam.wav, если нажать любую клавишу, то программа выйдет, и звук перестанет проигрываться.

Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#3 
uscheswoi_82 патриот18.02.25 16:55
NEW 18.02.25 16:55 
в ответ uscheswoi_82 18.02.25 16:10

Параметр SND_ASYNC подходит если Windows приложение постоянно запущенное, самое то подходит для компьютерных игр каких-нибудь например.

Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#4 
uscheswoi_82 патриот19.02.25 11:55
NEW 19.02.25 11:55 
в ответ uscheswoi_82 18.02.25 16:55

Продолжим вспоминать мультимедия.

Короче если нужно из ресурсов проиграть звуковой файл то нужно указать флаг SND_RESOURCE, вот пример:

#include <stdio.h>
#include <windows.h>
#include "resource.h"

int main(int argc, char *argv[]) {
  /* Загружаем файл из ресурса IDR_WAVE1 */
  PlaySound(MAKEINTRESOURCE(IDR_WAVE1),GetModuleHandle(NULL), SND_RESOURCE | SND_ASYNC);
  /* Специально нужна пауза, а то если выйдет из программы, звук перестанет проигрывать */
  system("pause");
  return 0;
}
Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#5 
uscheswoi_82 патриот19.02.25 12:17
NEW 19.02.25 12:17 
в ответ uscheswoi_82 19.02.25 11:55

В низкий уровень программирования я ещё вернусь. А теперь речь пойдёт о высоком уровне. Для этого буду использовать функцию mciSendString. Эта функция т.е. mciSendString может не только звуковые файлы проигрывать но и аудио CD, видео, и даже DVD видео.

Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#6 
uscheswoi_82 патриот19.02.25 13:03
NEW 19.02.25 13:03 
в ответ uscheswoi_82 19.02.25 12:17

1. Создадим в Embarcadero Dev-C++ новый проект Windows Application и язык выберем C (т.е. Си).

2. Добавим в проект библиотеку ../../Program Files (x86)/Embarcadero/Dev-Cpp/TDM-GCC-64/x86_64-w64-mingw32/lib/libwinmm.a.

3. Вот код main.c:

#define VIDEO_ID  "my_video"
#include <windows.h>
HWND hwndButton;
HWND hwndStatic;
char buf[1000];
LRESULT CALLBACK WndProc(HWND hwnd, 
                         UINT Message, 
                         WPARAM wParam, 
                         LPARAM lParam) {
  switch(Message) {
    case WM_COMMAND:
      sprintf(buf, "play %s", VIDEO_ID);
      mciSendString(buf, NULL, 0, 0);            
    break;
    case WM_CREATE:
      hwndButton = CreateWindow("BUTTON", "Play", WS_CHILD | WS_VISIBLE, 
      10, 10, 100, 20, hwnd, (HMENU)NULL, NULL, lParam);
      hwndStatic = CreateWindow("STATIC", "", WS_CHILD | WS_VISIBLE, 
      10, 40, 800, 600, hwnd, (HMENU)NULL, NULL, lParam);
      sprintf(buf, "open \"movie.avi\" type MPEGVideo alias %s parent %ld style child", 
      VIDEO_ID, (long)hwndStatic);
      mciSendString(buf, NULL, 0, 0);            
      sprintf(buf, "put %s window at 10 10 320 240 225", 
      VIDEO_ID);
      mciSendString(buf, NULL, 0, 0);            
    break;        
    case WM_DESTROY: {
      PostQuitMessage(0);
    break;
    }
    default:
      return DefWindowProc(hwnd, Message, wParam, lParam);
  }
  return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, 
                   HINSTANCE hPrevInstance, 
                   LPSTR lpCmdLine, 
                   int nCmdShow) {
  WNDCLASSEX wc;
  HWND hwnd;
  MSG msg;
  memset(&wc,0,sizeof(wc));
  wc.cbSize        = sizeof(WNDCLASSEX);
  wc.lpfnWndProc   = WndProc;
  wc.hInstance     = hInstance;
  wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  wc.lpszClassName = "usw82_simple_media_player";
  wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

  if(!RegisterClassEx(&wc)) {
    MessageBox(NULL, "Window Registration Failed!","Error!", 
    MB_ICONEXCLAMATION | MB_OK);
    return 0;
  }

  hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"usw82_simple_media_player",
  "Simple Media Player", 
  WS_VISIBLE | WS_OVERLAPPEDWINDOW,
  CW_USEDEFAULT,
  CW_USEDEFAULT,
  840,
  698,
  NULL,
  NULL,
  hInstance,
  NULL);
  if(hwnd == NULL) {
    MessageBox(NULL, "Window Creation Failed!","Error!", 
    MB_ICONEXCLAMATION | MB_OK);
  return 0;
  }

  while(GetMessage(&msg, NULL, 0, 0) > 0) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return msg.wParam;
}


4. Вуаля! Вот наш проигрыватель, он проигрывает видео т.е. avi-файл. Это видео я сам делал в программе Blender 2.79.



Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#7 
uscheswoi_82 патриот20.02.25 07:49
NEW 20.02.25 07:49 
в ответ uscheswoi_82 19.02.25 13:03

Продолжим вспоминать. Вспоминать будем на Borland C++ Builder 4


Короче я за 2 минуты сделал простенький видео медиа плеер. В Borland C++ Builder 4 есть компонент MediaPlayer:


Видео где будет отображаться у меня называется Panel1, а компонент, который проигрывает видео называется MediaPlayer1:



Нужно сделать следующее - AutoEnable = true, AutoOpen = true, Display = Panel1, FileName=C:\Windows\Clock.avi, VisibleButtons - btRecord = false, btEject = false:



Вуаля! А вот и наш простенький медиа плеер, который может проигрывать видео файлы:


Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#8 
uscheswoi_82 патриот20.02.25 09:49
NEW 20.02.25 09:49 
в ответ uscheswoi_82 20.02.25 07:49

Марк Цукерберг когда ещё учился вроде бы создал музыкальный проигрыватель на обычном Visual Basic, назывался Synapse Media Player, вот так выглядкл этот медиаплеер - https://windows-cdn.softpedia.com/screenshots/Synapse-Medi.... Я когда был школьником тоже пытался создать свой медиа плеер, и даже свой кодек см. Воспоминания свой кодек на VB6, 15.05.2024. Сегодня или завтра попробую создать на Visual Basic DivX проигрыватель.

Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#9 
uscheswoi_82 патриот20.02.25 10:00
NEW 20.02.25 10:00 
в ответ uscheswoi_82 20.02.25 09:49

Я буду делать на каком-то из этих Visual Basic-ов. У меня тут Visual Basic 4 Enterprise Edition, Visual Basic 5 Enterprise Edition, Visual Basic 6 Professional Edition:


Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#10 
uscheswoi_82 патриот20.02.25 10:12
NEW 20.02.25 10:12 
в ответ uscheswoi_82 20.02.25 10:00

Предумываем свой скрипт. Короче в Visual Basic и VBA есть функция split. Эта функция расщепляет строку на массив, спомощью конкретного делителя. Допустим в нашем скрипте алгоритм такой КОМАНДА потом пробел и парметры, например INTRO startup.avi.

Команда

Параметры

Пример

Описание

INTRO

имя_файла.avi

INTRO startup.avi

Запускается видео в самом начале

MENU_BG

имя_файла.jpeg

MENU_BG mainmenu.jpeg

Отображает картинку, которая служит менюшкой.

MENU_AU

имя_файла.mp3

MENU_AU mainmenu.mp3

Проигрывает аудио, пока находишься в меню.

MOVIE

имя_файла.avi

MOVIE gladiator.avi

Загружает видео, когда пользователь нажмёт на проигрывание, фильм запустится

HOTSPOTS

X, y, pos, x, y, pos, …

HOTSPOTS 10 10 0, 10 40, 500

При нажатие на видео, загружается позиция видео

Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#11 
uscheswoi_82 патриот22.02.25 08:44
NEW 22.02.25 08:44 
в ответ uscheswoi_82 20.02.25 07:49
Нужно сделать следующее - AutoEnable = true, AutoOpen = true, Display = Panel1, FileName=C:\Windows\Clock.avi, VisibleButtons - btRecord = false, btEject = false:


Главное забыл написать, нужно написать DeviceType=dtAVIVideo.

Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#12 
uscheswoi_82 патриот22.02.25 14:08
NEW 22.02.25 14:08 
в ответ uscheswoi_82 20.02.25 10:12

Тут опечатка:

Команда
Параметры
Пример
Описание
HOTSPOTS
X, y, pos, x, y, pos, …
HOTSPOTS 10 10 0, 10 40, 500
При нажатие на видео, загружается позиция видео

Правильно вот так:

Команда

Параметры

Пример

Описание

HOTSPOTS

x y w h pos, x y w h pos,

HOTSPOTS 10 10 100 20 0

При нажатие на видео, загружается позиция видео

Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#13 
uscheswoi_82 патриот22.02.25 14:15
NEW 22.02.25 14:15 
в ответ uscheswoi_82 22.02.25 14:08

Вот так будем парзить:

Sub Main()
  Dim strCmd as String = "HOTSPOTS 10 10 100 20 0"
  Dim arrResult() as String
  Dim i as Integer 
  arrResult = Split(strCmd, " ")
  For i = LBound(arrResult, 1) To UBound(arrResult, 1)
    MsgBox arrResult(i)
  Next i
End Sub


Результат работы алгоритма:

HOTSPOTS
10
10
100
20
0
Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#14 
uscheswoi_82 патриот22.02.25 14:30
NEW 22.02.25 14:30 
в ответ uscheswoi_82 22.02.25 14:15

HOTSPOTS - это команда, 10 10 100 20 0 - параметры.

Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#15 
uscheswoi_82 патриот16.03.25 20:27
NEW 16.03.25 20:27 
в ответ uscheswoi_82 22.02.25 14:30

Короче я почти сделал проигрыватель, где-то приблизительно на это 2 часа потратил:

Код frmPlayer.frm:

VERSION 5.00
Begin VB.Form frmPlayer 
   AutoRedraw      =   -1  'True
   BorderStyle     =   1  'Fixed Single
   Caption         =   "DivX проигрыватель v1.0"
   ClientHeight    =   570
   ClientLeft      =   45
   ClientTop       =   330
   ClientWidth     =   4290
   LinkTopic       =   "Form1"
   MaxButton       =   0   'False
   MinButton       =   0   'False
   ScaleHeight     =   570
   ScaleWidth      =   4290
   StartUpPosition =   3  'Windows Default
   Begin VB.CommandButton cmdStop 
      Caption         =   "Остановка"
      Height          =   375
      Left            =   960
      TabIndex        =   2
      Top             =   120
      Width           =   975
   End
   Begin VB.CommandButton cmdInfo 
      Caption         =   "Информация о фильме"
      Height          =   375
      Left            =   2040
      TabIndex        =   1
      Top             =   120
      Width           =   2175
   End
   Begin VB.CommandButton cmdPlay 
      Caption         =   "Пуск"
      Height          =   375
      Left            =   120
      TabIndex        =   0
      Top             =   120
      Width           =   735
   End
End
Attribute VB_Name = "frmPlayer"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Type DURATION
    hours As Integer
    minutes As Integer
    seconds As Integer
End Type
Dim bIsVideoOpened As Boolean
Dim strYear As String
Dim strTitle As String
Dim strMoveFileName As String
Dim strIntroFilename As String
Dim strMenuImageFilename As String
Dim strMenuBGMusic As String
Dim durMovieDuration As DURATION
Dim durBGAudioDuration As DURATION
Private Sub ReadDisk()
    'Const cStrCommand = "INTRO c:\divxplay\intro.avi"
    Dim strCmd As String
    Dim arrParams() As String
    Dim i As Integer
    'Если видео уже проигрывается, то выходит
    If bIsVideoOpened = True Then Exit Sub
    bIsVideoOpened = True
    'Показывает экран, на котором будет проигрываться видео
    frmMovieScreen.Show
    'Открывает файл starutp.cfg
    Open "C:\divxplay2\startup.cfg" For Input As #1
    'Пока файл незакрыт, читать данные
    Do While Not EOF(1)
    'Читаем каждую строчку в файле
    Input #1, strCmd
    'Если строчка не пустая, то запускается наш
    'интерпретатор
    If strCmd <> "" Then
        'Парзим строки, и разделяем команды и параметры
        Select Case GetCommand(strCmd)
            'Фильм года
            Case "YEAR"
             If getParametersCount(strCmd) > 0 Then
                arrParams = GetParameters(strCmd)
                strYear = arrParams(0)
             End If
            'Длительность фильма
            Case "MOVIEDURATION"
             Dim arrParamsMovieDuration() As String
             If getParametersCount(strCmd) > 0 Then
                arrParams = GetParameters(strCmd)
                arrParamsMovieDuration = Split(arrParams(1), ":")
                durMovieDuration.hours = CInt(arrParamsMovieDuration(0))
                durMovieDuration.minutes = CInt(arrParamsMovieDuration(1))
                durMovieDuration.seconds = CInt(arrParamsMovieDuration(2))
             End If
            'Длительность фоновой музыки
            Case "BGAUDIODURATION"
             Dim arrParamsBGAudioDuration() As String
             If getParametersCount(strCmd) > 0 Then
                arrParams = GetParameters(strCmd)
                arrParamsBGAudioDuration = Split(arrParams(1), ":")
                durBGAudioDuration.hours = CInt(arrParamsBGAudioDuration(0))
                durBGAudioDuration.minutes = CInt(arrParamsBGAudioDuration(1))
                durBGAudioDuration.seconds = CInt(arrParamsBGAudioDuration(2))
             End If
            'Название фильма
            Case "TITLE"
             If getParametersCount(strCmd) > 0 Then
                arrParams = GetParameters(strCmd)
                strTitle = arrParams(1)
                frmMovieScreen.Caption = arrParams(1)
             End If
            'Интро, запускается при запуске фильма
            Case "INTRO"
             If getParametersCount(strCmd) > 0 Then
                arrParams = GetParameters(strCmd)
                strIntroFilename = arrParams(1)
             End If
             'Картинка для менюшки
            Case "MENU_BG"
             If getParametersCount(strCmd) > 0 Then
                arrParams = GetParameters(strCmd)
                strMenuImageFilename = arrParams(1)
             End If
             'Музыка во время запуска меню
            Case "MENU_AU"
             If getParametersCount(strCmd) > 0 Then
                arrParams = GetParameters(strCmd)
                strMenuBGMusic = arrParams(1)
             End If
             'Устанавливает видео
            Case "MOVIE"
             If getParametersCount(strCmd) > 0 Then
                arrParams = GetParameters(strCmd)
                strMoveFileName = arrParams(1)
             End If
             'Для меню
            Case "HOTSPOTS"
             If getParametersCount(strCmd) > 0 Then
                arrParams = GetParameters(strCmd)
             End If
        End Select
    End If
    Loop
End Sub
Private Sub cmdInfo_Click()
    'Показывает информацию о CD диске
    If bIsVideoOpened = True Then
        MsgBox "Название фильма:" & strTitle & vbCrLf _
        & "Год:" & strYear & vbCrLf _
        & "Длительность фильма:" & CStr(durMovieDuration.hours) _
        & "часов(а), " & CStr(durMovieDuration.minutes) _
        & " минут, " & CStr(durMovieDuration.seconds) _
        & " секунд " _
        , vbInformation
    End If
End Sub
Private Sub cmdPlay_Click()
    'Считываем файл startup.cfg
    ReadDisk
End Sub
Private Sub Form_Load()
    'Инициализация
    strYear = ""
    strMoveFileName = ""
    strIntroFilename = ""
    strMenuImageFilename = ""
    strMenuBGMusic = ""
    strTitle = ""
    durBGAudioDuration.hours = 0
    durBGAudioDuration.minutes = 0
    durBGAudioDuration.seconds = 0
    durMovieDuration.hours = 0
    durMovieDuration.minutes = 0
    durMovieDuration.seconds = 0
    'Закрывает видео
    CloseVideo "vid1"
    bIsVideoOpened = False
End Sub
Private Sub Form_Unload(Cancel As Integer)
    'Если окно закрывается
    If bIsVideoOpened = True Then
        'То закрыть видео
        CloseVideo "vid1"
    End If
    'Закрыть экран, но котором будет проигрывать видео
    Unload frmMovieScreen
End Sub



Код modMain.bas:

Attribute VB_Name = "modMain"
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'Возвращает количество параметров в команде
Public Function getParametersCount(ByVal strCmd As String) As Integer
  Dim arrResult() As String
  'Пробелом отделяются параметры от команды.
  'Функция Split расщепляет строку спомощью делителя,
  'а если быть точнее делитель у нас пробел.
  arrResult = Split(strCmd, " ")
  'Возвращает количество параметров
  getParametersCount = UBound(arrResult, 1)
End Function
'Возвращает названия команды
Public Function GetCommand(ByVal strCmd As String) As String
  Dim arrResult() As String
  'Пробелом отделяются параметры от команды.
  'Функция Split расщепляет строку спомощью делителя,
  'а если быть точнее делитель у нас пробел.
  arrResult = Split(strCmd, " ")
  GetCommand = arrResult(LBound(arrResult, 1))
End Function
'Возвращает параметры
Public Function GetParameters(ByVal strCmd As String) As String()
  Dim arrResult() As String
  Dim strCmdNew As String
  Dim i As Integer
  'Пробелом отделяются параметры от команды.
  'Функция Split расщепляет строку спомощью делителя,
  'а если быть точнее делитель у нас пробел.
  arrResult = Split(strCmd, " ")
  'Отсекам команду
  strCmdNew = Mid(strCmd, Len(arrResult(0)) + 1, Len(strCmd))
  'Если параметров больше чем один, то:
  If getParametersCount(strCmdNew) > 1 Then
    'Пробелом отделяются параметры от команды.
    'Функция Split расщепляет строку спомощью делителя,
    'а если быть точнее делитель у нас пробел.
    arrResult = Split(strCmdNew, " ")
    'Возвращаем массив параметро
    GetParameters = arrResult
  Else
    ' Если только один параметр, то возвращет массив с одним параметром
    arrResult(0) = strCmdNew
    GetParameters = arrResult
  End If
End Function



Код modMCI.bas:

Attribute VB_Name = "modMCI"
'API Функция нужна для проигрывание мультимедийных файлов
Public Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
(ByVal lpstrCommand As String, ByVal lpstrReturnString As String, _
ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long
'Открывает видео
Public Sub OpenVideo(ByVal strFileName, _
                     ByVal strAlias As String, _
                     ByVal lngHwnd As Double)
    Dim strCmd As String
    Dim lpStrReturnValue As String
    Dim lngLength As Integer
    strCmd = "open """ & strFileName _
             & """ type MPEGVideo alias " _
             & strAlias _
             & " parent " & CStr(lngHwnd) & " style child"
    mciSendString strCmd, lpStrReturnValue, lngLength, lngHwnd
    strCmd = "put " & strAlias & " window at 10 10 320 240 225"
    mciSendString strCmd, lpStrReturnValue, lngLength, lngHwnd
End Sub
'Проигрывает видео
Public Sub PlayVideo(ByVal strAlias As String)
    Dim strCmd As String
    Dim lpStrReturnValue As String
    Dim lngLength As Integer
    strCmd = "play " & strAlias
    mciSendString strCmd, lpStrReturnValue, lngLength, lngHwnd
End Sub
'Закрывает видео
Public Sub CloseVideo(ByVal strAlias As String)
    Dim strCmd As String
    Dim lpStrReturnValue As String
    Dim lngLength As Integer
    strCmd = "stop " + strAlias
    mciSendString strCmd, lpStrReturnValue, lngLength, lngHwnd
    strCmd = "close " + strAlias
    mciSendString strCmd, lpStrReturnValue, lngLength, lngHwnd
End Sub



Пример startup.cfg:

TITLE Гладиатор
YEAR 2000
MOVIEDURATION 01:01:01
INTRO intro.avi
MENU_BG menu.bmp
MENU_AU menu.mp3
MOVIE gladiator.avi
HOTSPOTS 0 0 0 0 0 0 0 0 0 0 0 0
Если я кому-то отвечаю, это не значит что я ему симпатизирую, каждый остаётся при своём мнение
#16