• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            JACKY_ZZ[貓貓愛吃魚]

            春風拂面兩頰紅,秋葉灑地一片金。 夏荷搖曳一身輕,冬雪覆蓋大地銀。
            posts - 30, comments - 123, trackbacks - 0, articles - 0
            這是一個基于Ffmpeg解碼器的簡單播放器,怎么在Windows上編譯Ffmpeg可以在網上找到很多,開發環境是Windows XP SP3+VS2008,其中DirectSound控制單元來自jdk1.6源碼。我的Ffmpeg編譯環境是MSYS+MinGW,GCC版本為4.4.0,采取靜態無DEBUG方式編譯,得到libavcodec.a、libavformat.a和libavutil.a三個靜態庫,將靜態庫引入工程,代碼如下:
             1 #pragma once
             2 
             3 #define WIN32_LEAN_AND_MEAN
             4 
             5 #include "targetver.h"
             6 #include <windows.h>
             7 #include <commdlg.h>
             8 
             9 #include <stdlib.h>
            10 #include <malloc.h>
            11 #include <memory.h>
            12 #include <tchar.h>
            13 #include <math.h>
            14 #include <mmsystem.h>
            15 #include <dsound.h>
            16 #include <commctrl.h>
            17 
            18 #include <list>
            19 #include <vector>
            20 using namespace std;
            21 
            22 #pragma comment(lib, "winmm.lib")
            23 #pragma comment(lib, "dsound.lib")
            24 #pragma comment(lib, "msimg32.lib")
            25 #pragma comment(lib, "wsock32.lib")
            26 #pragma comment(lib, "comctl32.lib")
            27 
            28 #ifdef __cplusplus
            29 extern "C" {
            30 #endif
            31 
            32 #pragma warning(disable : 4005)
            33 #pragma warning(disable : 4049)
            34 
            35 #include "./include/avcodec.h"
            36 #include "./include/avformat.h"
            37 #include "./include/avutil.h"
            38 #include "./include/mem.h"
            39 
            40 #pragma comment(lib, "./lib/libgcc.a")
            41 #pragma comment(lib, "./lib/libmingwex.a")
            42 #pragma comment(lib, "./lib/libcoldname.a")
            43 
            44 #pragma comment(lib, "./lib/libavcodec.a")
            45 #pragma comment(lib, "./lib/libavformat.a")
            46 #pragma comment(lib, "./lib/libavutil.a")
            47 
            48 
            49 #ifdef __cplusplus
            50 }
            51 #endif
            52 
            53 #define USE_DAUDIO TRUE
            54 #define round(a) ((long)floor((a) + 0.5f))
            主程序代碼如下:
              1 #include "stdafx.h"
              2 #include "SimpleFfmpegPlayer.h"
              3 #include "DirectSound.h"
              4 
              5 #define MAX_LOADSTRING 100
              6 #define BLOCK_SIZE        4608
              7 
              8 // Thread Message Define Here
              9 #define TM_PLAY            0
             10 #define TM_PAUSE        1
             11 #define TM_RESUME        2
             12 #define TM_SEEK            3
             13 #define TM_STOP            4
             14 #define TM_OPENFILE        5
             15 #define TM_PREVIOUS        6
             16 #define TM_NEXT            7
             17 #define TM_EOF            8
             18 #define TM_PLAYITEM        9
             19 
             20 struct StartParameter
             21 {
             22     HWND hMainWnd;
             23     HANDLE hThreadReadyEvent;
             24 };
             25 
             26 HINSTANCE hInst;
             27 TCHAR szTitle[MAX_LOADSTRING];
             28 TCHAR szWindowClass[MAX_LOADSTRING];
             29 HWND hMainWindow = NULL;
             30 HWND hTrackBar = NULL;
             31 HWND hStatic = NULL;
             32 
             33 DWORD dwMainLoopThreadId = 0;
             34 HANDLE hMainLoopThread = NULL;
             35 
             36 BOOL Playing = FALSE;
             37 
             38 TCHAR szFileName[MAX_PATH];
             39 int gTotalSeconds;
             40 int gCurPlaySeconds;
             41 int gPosition;
             42 
             43 HFONT hFont;
             44 
             45 ATOM                MyRegisterClass(HINSTANCE hInstance);
             46 BOOL                InitInstance(HINSTANCE, int);
             47 LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
             48 INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
             49 DWORD WINAPI        MainLoopThreadProc(VOID*);
             50 LRESULT CALLBACK    StaticWndProc(HWND, UINT, WPARAM, LPARAM);
             51 
             52 #define SUPPORT_FILTER _TEXT("All supported files\0*.aac;*.ape;*.flac;*.mp3;*.mpc;*.ogg;*.tta;*.wav;*.wma;*.wv\0") \
             53     _TEXT("AAC files(*.aac)\0*.aac\0") \
             54     _TEXT("APE files(*.ape)\0*.ape\0") \
             55     _TEXT("FLAC files(*.flac)\0*.flac\0") \
             56     _TEXT("MP3 files(*.mp3)\0*.mp3\0") \
             57     _TEXT("MPC files(*.mpc)\0*.mpc\0") \
             58     _TEXT("Ogg vorbis files(*.ogg)\0*.ogg\0") \
             59     _TEXT("TTA files(*.tta)\0*.tta\0") \
             60     _TEXT("Wave files(*.wav)\0*.wav\0") \
             61     _TEXT("WMA files(*.wma)\0*.wma\0") \
             62     _TEXT("Wavpack files(*.wv)\0*.wv\0") \
             63     _TEXT("All files(*.*)\0*.*\0")
             64 
             65 typedef struct AudioState
             66 {
             67     AVFormatContext* pFmtCtx;
             68     AVCodecContext* pCodecCtx;
             69     AVCodec* pCodec;
             70 
             71 #ifdef OUTPUT_INFORMATS
             72     AVInputFormat* ifmt;
             73 #endif
             74 
             75     uint8_t* audio_buf1;
             76     uint8_t* audio_buf;
             77     unsigned int audio_buf_size;
             78     unsigned int buffer_size;
             79     int audio_buf_index;
             80     AVPacket audio_pkt_temp;
             81     AVPacket audio_pkt;
             82     uint8_t* audio_pkt_data;
             83     int audio_pkt_size;
             84     int stream_index;
             85 } AudioState;
             86 
             87 long align(long bytes, int blockSize) {
             88     // prevent null pointers
             89     if (blockSize <= 1)
             90         return bytes;
             91 
             92     return bytes - (bytes % blockSize);
             93 }
             94 
             95 long millis2bytes(int samplerate, long millis, int frameSize)
             96 {
             97     long result = (long) (millis * samplerate / 1000.0f * frameSize);
             98     return align(result, frameSize);
             99 }
            100 
            101 long bytes2millis(int samplerate, long bytes, int frameSize) {
            102     return (long) (bytes / samplerate * 1000.0f / frameSize);
            103 }
            104 
            105 int audio_decode_frame(AudioState* pState)
            106 {
            107 
            108     AVPacket* pkt_temp = &pState->audio_pkt_temp;
            109     AVPacket* pkt = &pState->audio_pkt;
            110     AVCodecContext* dec= pState->pCodecCtx;
            111     int len = 0, data_size = sizeof(pState->audio_buf1);
            112     int err = 0;
            113 
            114     for( ; ; )
            115     {
            116         while (pkt_temp->size > 0)
            117         {
            118             data_size = pState->buffer_size;
            119             len = avcodec_decode_audio3(dec, (int16_t*)pState->audio_buf1, &data_size, pkt_temp);
            120             if (len < 0)
            121             {
            122                 /* if error, we skip the frame */
            123                 pkt_temp->size = 0;
            124                 break;
            125             }
            126 
            127             pkt_temp->data += len;
            128             pkt_temp->size -= len;
            129 
            130             if (data_size <= 0)
            131                 continue;
            132 
            133             pState->audio_buf = pState->audio_buf1;
            134             return data_size;
            135         }
            136 
            137         if (pkt->data)
            138             av_free_packet(pkt);
            139 
            140         if((err = av_read_frame(pState->pFmtCtx, pkt)) < 0)
            141             return -1;
            142 
            143         pkt_temp->data = pkt->data;
            144         pkt_temp->size = pkt->size;
            145     }
            146 
            147     return -1;
            148 }
            149 
            150 int read_buffer(AudioState* pState, void* buffer, int buf_size)
            151 {
            152     int len = buf_size;
            153     uint8_t* pbuffer = (uint8_t*)buffer;
            154     int audio_size = 0;
            155     int len1 = 0;
            156     int size = 0;
            157 
            158     while(len > 0)
            159     {
            160         if(pState->audio_buf_index >= (int)pState->audio_buf_size)
            161         {
            162             audio_size = audio_decode_frame(pState);
            163             if(audio_size < 0)
            164                 return (size > 0? size : -1;
            165 
            166             pState->audio_buf_size = audio_size;
            167             pState->audio_buf_index = 0;
            168         }
            169 
            170         len1 = pState->audio_buf_size - pState->audio_buf_index;
            171         if(len1 > len)
            172             len1 = len;
            173 
            174         memcpy(pbuffer, (uint8_t *)pState->audio_buf + pState->audio_buf_index, len1);
            175 
            176         len -= len1;
            177         pbuffer += len1;
            178         size += len1;
            179         pState->audio_buf_index += len1;
            180     }
            181 
            182     return size;
            183 }
            184 
            185 int APIENTRY _tWinMain(HINSTANCE hInstance,
            186                      HINSTANCE hPrevInstance,
            187                      LPTSTR    lpCmdLine,
            188                      int       nCmdShow)
            189 {
            190     UNREFERENCED_PARAMETER(hPrevInstance);
            191     UNREFERENCED_PARAMETER(lpCmdLine);
            192 
            193     MSG msg;
            194     HACCEL hAccelTable;
            195 
            196     INITCOMMONCONTROLSEX cex = {sizeof(INITCOMMONCONTROLSEX),
            197         ICC_BAR_CLASSES | ICC_PROGRESS_CLASS};
            198     BOOL ret = InitCommonControlsEx(&cex);
            199 
            200     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
            201     LoadString(hInstance, IDC_SIMPLEFFMPEGPLAYER, szWindowClass, MAX_LOADSTRING);
            202     MyRegisterClass(hInstance);
            203 
            204     if (!InitInstance (hInstance, nCmdShow))
            205     {
            206         return FALSE;
            207     }
            208 
            209     hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SIMPLEFFMPEGPLAYER));
            210 
            211     while (GetMessage(&msg, NULL, 00))
            212     {
            213         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
            214         {
            215             TranslateMessage(&msg);
            216             DispatchMessage(&msg);
            217         }
            218     }
            219 
            220     return (int) msg.wParam;
            221 }
            222 
            223 ATOM MyRegisterClass(HINSTANCE hInstance)
            224 {
            225     WNDCLASSEX wcex;
            226 
            227     wcex.cbSize = sizeof(WNDCLASSEX);
            228 
            229     wcex.style            = CS_HREDRAW | CS_VREDRAW;
            230     wcex.lpfnWndProc    = WndProc;
            231     wcex.cbClsExtra        = 0;
            232     wcex.cbWndExtra        = 0;
            233     wcex.hInstance        = hInstance;
            234     wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SIMPLEFFMPEGPLAYER));
            235     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
            236     wcex.hbrBackground    = (HBRUSH)(COLOR_BTNFACE+1);
            237     wcex.lpszMenuName    = MAKEINTRESOURCE(IDC_SIMPLEFFMPEGPLAYER);
            238     wcex.lpszClassName    = szWindowClass;
            239     wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
            240 
            241     return RegisterClassEx(&wcex);
            242 }
            243 
            244 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
            245 {
            246    HWND hWnd;
            247 
            248    hInst = hInstance;
            249 
            250    DWORD dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
            251    hWnd = CreateWindow(szWindowClass, szTitle, dwStyle,
            252       00320100, NULL, NULL, hInstance, NULL);
            253 
            254    if (!hWnd)
            255    {
            256       return FALSE;
            257    }
            258 
            259    hMainWindow = hWnd;
            260 
            261    hFont = CreateFont(18,0,0,0,FW_BLACK,FALSE,FALSE,FALSE,
            262        GB2312_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
            263        DEFAULT_QUALITY,FIXED_PITCH | FF_MODERN,_T("Tahoma"));
            264 
            265    RECT r = {0000};
            266    GetWindowRect(hMainWindow, &r);
            267    hTrackBar = CreateWindowEx(0, TRACKBAR_CLASS, _T(""), WS_CHILD | WS_VISIBLE | TBS_BOTH | TBS_NOTICKS,
            268        r.left + 4, (r.bottom - r.top) / 6 + 430018, hMainWindow, NULL, hInstance, NULL);
            269    SendMessage(hTrackBar, TBM_SETRANGE, (WPARAM)FALSE, (LPARAM) MAKELONG (0100));
            270    SendMessage(hTrackBar, TBM_SETLINESIZE, (WPARAM)0, (LPARAM)5);
            271    SendMessage(hTrackBar, TBM_SETPAGESIZE, (WPARAM)0, (LPARAM)5);
            272 
            273    GetClientRect(hMainWindow, &r);
            274    hStatic = CreateWindowEx(0, WC_STATIC, _T("00:00/00:00"), WS_CHILD | WS_VISIBLE | WS_OVERLAPPED | SS_CENTER | SS_LEFT,
            275        (r.right - r.left) / 4 + 11010018, hMainWindow, NULL, hInstance, NULL);
            276 
            277    SetWindowLong(hStatic, GWL_WNDPROC, (LONG)StaticWndProc);
            278 
            279    ShowWindow(hWnd, nCmdShow);
            280    UpdateWindow(hWnd);
            281 
            282    return TRUE;
            283 }
            284 
            285 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
            286 {
            287     int wmId, wmEvent;
            288     PAINTSTRUCT ps;
            289     HDC hdc;
            290     TCHAR buffer[128= {0};
            291 
            292     switch (message)
            293     {
            294     case WM_COMMAND:
            295         wmId    = LOWORD(wParam);
            296         wmEvent = HIWORD(wParam);
            297 
            298         switch (wmId)
            299         {
            300         case IDM_ABOUT:
            301             DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            302             break;
            303         case IDM_EXIT:
            304             DestroyWindow(hWnd);
            305             break;
            306         case ID_PLAY:
            307             {
            308                 if(Playing == TRUE)
            309                     break;
            310 
            311                 OPENFILENAME ofn = {0};
            312                 ofn.lStructSize = sizeof(ofn);
            313                 ofn.hwndOwner = hMainWindow;
            314                 ofn.lpstrFile = szFileName;
            315                 ofn.lpstrFile[0= _T('\0');
            316                 ofn.nMaxFile = sizeof(szFileName) / sizeof(szFileName[0]);
            317                 ofn.lpstrFilter = SUPPORT_FILTER;
            318                 ofn.nFilterIndex = 1;
            319                 ofn.lpstrFileTitle = NULL;
            320                 ofn.nMaxFileTitle = 0;
            321                 ofn.lpstrInitialDir = NULL;
            322                 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;
            323 
            324                 if(GetOpenFileName(&ofn) == TRUE)
            325                 {
            326                     if(hMainLoopThread && dwMainLoopThreadId && Playing == FALSE)
            327                         PostThreadMessage(dwMainLoopThreadId, TM_PLAY, 00);
            328                 }
            329             }
            330             break;
            331         case ID_STOP:
            332             {
            333                 if(Playing == TRUE && hMainLoopThread && dwMainLoopThreadId)
            334                     PostThreadMessage(dwMainLoopThreadId, TM_EOF, 00);
            335             }
            336             break;
            337         default:
            338             return DefWindowProc(hWnd, message, wParam, lParam);
            339         }
            340         break;
            341     case WM_PAINT:
            342         hdc = BeginPaint(hWnd, &ps);
            343 
            344         EndPaint(hWnd, &ps);
            345         break;
            346     case WM_DESTROY:
            347         if(hMainLoopThread && dwMainLoopThreadId)
            348         {
            349             PostThreadMessage(dwMainLoopThreadId, TM_STOP, 00);
            350 
            351             CloseHandle(hMainLoopThread);
            352             hMainLoopThread = NULL;
            353         }
            354 
            355         DeleteObject(hFont);
            356         DestroyWindow(hTrackBar);
            357         DestroyWindow(hStatic);
            358         PostQuitMessage(0);
            359         break;
            360     case WM_NOTIFY:
            361         {
            362             NMHDR* pNMHDR = (NMHDR*)lParam;
            363             if(pNMHDR->hwndFrom == hTrackBar)
            364             {
            365                 LRESULT ret = SendMessage(hTrackBar, TBM_GETPOS, 00);
            366                 if( ret != gPosition && Playing)
            367                     PostThreadMessage(dwMainLoopThreadId, TM_SEEK, (WPARAM)ret, 0);
            368             }
            369         }
            370         break;
            371     case WM_CREATE:
            372         {
            373             // start main play loop thread
            374             HANDLE hThreadReadyEvent = CreateEvent(NULL, TRUE, FALSE, _T("ThreadReadyEvent"));
            375 
            376             StartParameter startParam = {hWnd, hThreadReadyEvent};
            377 
            378             dwMainLoopThreadId = 0;
            379             hMainLoopThread = CreateThread(NULL, 0, MainLoopThreadProc, &startParam, 
            380                 CREATE_SUSPENDED, &dwMainLoopThreadId);
            381 
            382             ResumeThread(hMainLoopThread);
            383             WaitForSingleObject(hThreadReadyEvent, INFINITE);
            384 
            385             CloseHandle(hThreadReadyEvent);
            386             hThreadReadyEvent = NULL;
            387         }
            388         break;
            389     default:
            390         return DefWindowProc(hWnd, message, wParam, lParam);
            391     }
            392     return 0;
            393 }
            394 
            395 LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
            396 {
            397     PAINTSTRUCT ps;
            398     HDC hdc;
            399     HFONT holdfont;
            400     TCHAR buffer[MAX_PATH] = {0};
            401     RECT r = {0};
            402 
            403     switch(message)
            404     {
            405     case WM_PAINT :
            406         {
            407             hdc = BeginPaint(hWnd, &ps);
            408 
            409             GetClientRect(hWnd, &r);
            410             FillRect(hdc, &r, (HBRUSH)(COLOR_BTNFACE+1));
            411             
            412             SetBkMode(hdc, TRANSPARENT);
            413 
            414             GetWindowText(hWnd, buffer, MAX_PATH);
            415             holdfont = (HFONT)SelectObject(hdc, hFont);
            416             TextOut(hdc, 00, buffer, _tcslen(buffer));
            417             SelectObject(hdc, holdfont);
            418 
            419             EndPaint(hWnd, &ps);
            420         }
            421         break;
            422     case WM_ERASEBKGND:
            423         return 1;
            424     default:
            425         return DefWindowProc(hWnd, message, wParam, lParam);
            426     }
            427 
            428     return 0;
            429 }
            430 
            431 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
            432 {
            433     UNREFERENCED_PARAMETER(lParam);
            434     switch (message)
            435     {
            436     case WM_INITDIALOG:
            437         return (INT_PTR)TRUE;
            438 
            439     case WM_COMMAND:
            440         if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
            441         {
            442             EndDialog(hDlg, LOWORD(wParam));
            443             return (INT_PTR)TRUE;
            444         }
            445         break;
            446     }
            447     return (INT_PTR)FALSE;
            448 }
            449 
            450 DWORD WINAPI MainLoopThreadProc(VOID* pParam)
            451 {
            452     StartParameter* pStartParam = (StartParameter*)pParam;
            453     BOOL bTerminateThread = FALSE;
            454 
            455     // register all codecs.
            456     av_register_all();
            457     SetEvent(pStartParam->hThreadReadyEvent);
            458 
            459     AudioState state = {0};
            460     int buffer_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3/ 2;
            461     memset(&state, 0sizeof(AudioState));
            462 
            463     int err = 0;
            464     char filepath[MAX_PATH] = {0};
            465 
            466     __int64 duration = 0;
            467     int totalSeconds = 0;
            468     int minute = 0;
            469     int second = 0;
            470     int totalMinute = 0;
            471     int totalSecond = 0;
            472 
            473     int channels = 0;
            474     int samplerate = 0;
            475     int bitpersample = 16;
            476 
            477     DS_Info* info = NULL;
            478     int frameSize = 0;
            479     long bufferSize = 0;
            480     int bytesPerSec = 0;
            481     long waitTime = 0;
            482     int deviceCount = 0;
            483 
            484     DWORD readBytes = 0;
            485     char input_buffer[BLOCK_SIZE] = {0};
            486     TCHAR szTime[20= {0};
            487     TCHAR szPosition[10= {0};
            488 
            489     do 
            490     {
            491         MSG msg = {0};
            492         while (PeekMessage(&msg, NULL, 00, PM_REMOVE))
            493         {
            494             switch(msg.message)
            495             {
            496             case TM_PLAY:
            497                 {
            498 
            499 #ifdef _UNICODE
            500                     WideCharToMultiByte(CP_ACP, 0, szFileName, -1, filepath, sizeof(filepath) / sizeof(char), NULL, NULL);
            501 #else
            502                     memcpy(filepath, szFileName, sizeof(filepath) / sizeof(char));
            503 #endif
            504 
            505                     err = av_open_input_file(&state.pFmtCtx, filepath, NULL, 0, NULL);
            506                     if(err < 0)
            507                     {
            508                         TCHAR buffer[2*MAX_PATH];
            509                         _stprintf_s(buffer, sizeof(TCHAR) * (2 * MAX_PATH), _T("can not open file %s."), filepath);
            510                         MessageBox(hMainWindow, buffer, _T("Error"), MB_OK | MB_ICONEXCLAMATION);
            511 
            512                         Playing = FALSE;
            513 
            514                         if(hMainLoopThread && dwMainLoopThreadId)
            515                             PostThreadMessage(dwMainLoopThreadId, TM_EOF, 00);
            516 
            517                         break;
            518                     }
            519 
            520                     err = av_find_stream_info(state.pFmtCtx);
            521                     if(err < 0)
            522                     {
            523                         TCHAR buffer[2*MAX_PATH];
            524                         _stprintf_s(buffer, sizeof(TCHAR) * (2 * MAX_PATH), _T("can not find stream info of file %s."), filepath);
            525                         MessageBox(hMainWindow, buffer, _T("Error"), MB_OK | MB_ICONEXCLAMATION);
            526 
            527                         Playing = FALSE;
            528 
            529                         if(hMainLoopThread && dwMainLoopThreadId)
            530                             PostThreadMessage(dwMainLoopThreadId, TM_EOF, 00);
            531 
            532                         break;
            533                     }
            534 
            535                     int index = -1;
            536                     for(unsigned int i = 0; i < state.pFmtCtx->nb_streams; i++)
            537                     {
            538                         if(state.pFmtCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
            539                         {
            540                             state.pCodecCtx = state.pFmtCtx->streams[i]->codec;
            541                             index = i;
            542                             state.stream_index = i;
            543                             break;
            544                         }
            545                     }
            546 
            547                     if(!state.pCodecCtx)
            548                     {
            549                         MessageBox(hMainWindow, _T("can not get codec context."), _T("Error"), MB_OK | MB_ICONEXCLAMATION);
            550                         av_close_input_file(state.pFmtCtx);
            551 
            552                         Playing = FALSE;
            553 
            554                         if(hMainLoopThread && dwMainLoopThreadId)
            555                             PostThreadMessage(dwMainLoopThreadId, TM_EOF, 00);
            556 
            557                         break;
            558                     }
            559 
            560                     state.pCodec = avcodec_find_decoder(state.pCodecCtx->codec_id);
            561                     if(!state.pCodec || avcodec_open(state.pCodecCtx, state.pCodec) < 0)
            562                     {
            563                         MessageBox(hMainWindow, _T("can not open codec."), _T("Error"), MB_OK | MB_ICONEXCLAMATION);
            564                         av_close_input_file(state.pFmtCtx);
            565 
            566                         Playing = FALSE;
            567 
            568                         if(hMainLoopThread && dwMainLoopThreadId)
            569                             PostThreadMessage(dwMainLoopThreadId, TM_EOF, 00);
            570 
            571                         break;
            572                     }
            573 
            574                     duration = state.pFmtCtx->duration;
            575                     totalSeconds = (int)(duration / 1000000L);
            576                     gTotalSeconds = totalSeconds;
            577                     totalMinute = (int)(totalSeconds / 60);
            578                     totalSecond = (int)(totalSeconds % 60);
            579 
            580                     state.audio_buf1 = (uint8_t*)av_mallocz(buffer_size);
            581                     state.buffer_size = buffer_size;
            582 
            583                     channels = state.pCodecCtx->channels;
            584                     samplerate = state.pCodecCtx->sample_rate;
            585 
            586                     bitpersample = 16;
            587                     switch(state.pCodecCtx->sample_fmt)
            588                     {
            589                     case SAMPLE_FMT_U8:
            590                         bitpersample = 8;
            591                         break;
            592                     case SAMPLE_FMT_S16:
            593                         bitpersample = 16;
            594                         break;
            595                     case SAMPLE_FMT_S32:
            596                         bitpersample = 32;
            597                         break;
            598                     case SAMPLE_FMT_FLT:
            599                         bitpersample = sizeof(double* 8;
            600                         break;
            601                     default:
            602                         bitpersample = 0;
            603                         break;
            604                     }
            605 
            606                     frameSize = (channels == 1? 2 : 4;
            607                     bufferSize = millis2bytes(samplerate, 500, frameSize);
            608                     bytesPerSec = samplerate * frameSize;
            609 
            610                     waitTime = bytes2millis(samplerate, bufferSize, frameSize) / 4;
            611                     if(waitTime < 10) waitTime = 1;
            612                     if(waitTime > 1000) waitTime = 1000;
            613 
            614                     deviceCount = DAUDIO_GetDirectAudioDeviceCount();
            615                     info = (DS_Info*)DAUDIO_Open(001, DAUDIO_PCM, (float)samplerate,
            616                         bitpersample, frameSize, channels, TRUE, FALSE, bufferSize);
            617 
            618                     if(info != NULL && DAUDIO_Start((void*)info, TRUE))
            619                     {
            620                         Playing = TRUE;
            621                         PostMessage(hTrackBar, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)0);
            622                     }
            623                 }
            624                 break;
            625             case TM_STOP:
            626                 {
            627                     if(info)
            628                     {
            629                         DAUDIO_Stop((void*)info, TRUE);
            630                         DAUDIO_Close((void*)info, TRUE);
            631                         info = NULL;
            632 
            633                         av_free(state.audio_buf1);
            634                         state.audio_buf1 = NULL;
            635 
            636                         avcodec_close(state.pCodecCtx);
            637                         av_close_input_file(state.pFmtCtx);
            638                     }
            639 
            640                     Playing = FALSE;
            641                     bTerminateThread = TRUE;
            642                 }
            643                 break;
            644             case TM_EOF:
            645                 {
            646                     if(info)
            647                     {
            648                         DAUDIO_Stop((void*)info, TRUE);
            649                         DAUDIO_Close((void*)info, TRUE);
            650                         info = NULL;
            651 
            652                         av_free(state.audio_buf1);
            653                         state.audio_buf1 = NULL;
            654 
            655                         avcodec_close(state.pCodecCtx);
            656                         av_close_input_file(state.pFmtCtx);
            657                     }
            658 
            659                     SendMessage(hTrackBar, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)0);
            660 
            661                     _stprintf_s(szTime, sizeof(szTime)/sizeof(szTime[0]), _T("%02d:%02d/%02d:%02d"), 
            662                         0000);
            663                     SendMessage(hStatic, WM_SETTEXT, (WPARAM)0, (LPARAM)szTime);
            664 
            665                     RECT r = {0};
            666                     GetClientRect(hStatic, &r);
            667                     InvalidateRect(hStatic, &r, FALSE);
            668 
            669                     Playing = FALSE;
            670                 }
            671                 break;
            672             case TM_SEEK:
            673                 {
            674                     if(Playing == TRUE && info != NULL)
            675                     {
            676                         MSG msg2;
            677                         if (PeekMessage(&msg2, NULL, TM_SEEK, TM_SEEK, PM_NOREMOVE) == FALSE)
            678                         {
            679                             int seekPosition = (int)msg.wParam;
            680                             int timestamp = (int)(gTotalSeconds * (float)seekPosition/100);
            681                             int ret = av_seek_frame(state.pFmtCtx, -1, timestamp * AV_TIME_BASE, 0);
            682                             avcodec_flush_buffers(state.pCodecCtx);
            683                             info->bytesPos = timestamp * bytesPerSec;
            684                             DAUDIO_Flush((void*)info, TRUE);
            685                         }
            686                     }
            687                 }
            688                 break;
            689             default:
            690                 break;
            691             }
            692         }
            693 
            694         if(bTerminateThread == TRUE)
            695             break;
            696 
            697         if(Playing == TRUE && info != NULL)
            698         {
            699             memset(input_buffer, 0sizeof(input_buffer));
            700             readBytes = 0;
            701 
            702             readBytes = read_buffer(&state, input_buffer, BLOCK_SIZE);
            703             if(readBytes == -1)
            704             {
            705                 Sleep(250);
            706                 Playing = FALSE;
            707 
            708                 if(hMainLoopThread && dwMainLoopThreadId)
            709                     PostThreadMessage(dwMainLoopThreadId, TM_EOF, 00);
            710 
            711                 SendMessage(hTrackBar, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)0);
            712 
            713                 _stprintf_s(szTime, sizeof(szTime)/sizeof(szTime[0]), _T("%02d:%02d/%02d:%02d"), 
            714                     0000);
            715                 SendMessage(hStatic, WM_SETTEXT, (WPARAM)0, (LPARAM)szTime);
            716 
            717                 RECT r = {0};
            718                 GetClientRect(hStatic, &r);
            719                 InvalidateRect(hStatic, &r, FALSE);
            720 
            721                 goto NextLoop;
            722             }
            723 
            724             DWORD len = readBytes;
            725             DWORD offset = 0;
            726             DWORD written = 0;
            727 
            728             for( ; ; )
            729             {
            730                 int thisWritten = DAUDIO_Write((void*)info, input_buffer+offset, len);
            731                 if(thisWritten < 0)
            732                     break;
            733 
            734                 len -= thisWritten;
            735                 written += thisWritten;
            736                 if(len > 0)
            737                 {
            738                     offset += thisWritten;
            739                     Sleep(waitTime);
            740                 }
            741                 else break;
            742             }
            743 
            744             // update progress
            745             {
            746                 __int64 wFp = DAUDIO_GetLongFramePosition((void*)info, TRUE);
            747                 __int64 byteLen = wFp * frameSize;
            748                 gCurPlaySeconds = (int)byteLen / bytesPerSec;
            749 
            750                 int seconds = (int)byteLen / bytesPerSec;
            751                 minute = (int)(seconds / 60);
            752                 second = (int)(seconds % 60);
            753 
            754                 _stprintf_s(szTime, sizeof(szTime)/sizeof(szTime[0]), _T("%02d:%02d/%02d:%02d"), 
            755                     minute, second, totalMinute, totalSecond);
            756                 SendMessage(hStatic, WM_SETTEXT, (WPARAM)0, (LPARAM)szTime);
            757 
            758                 RECT r = {0};
            759                 GetClientRect(hStatic, &r);
            760                 InvalidateRect(hStatic, &r, FALSE);
            761 
            762                 float percent = (float)seconds / totalSeconds;
            763                 int position = round(percent * 100);
            764                 if(position >= 100)
            765                     position = 100;
            766 
            767                 gPosition = position;
            768                 PostMessage(hTrackBar, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)position);
            769 
            770                 // _stprintf_s(szPosition, 10, _T("%02d\n"), position);
            771                 // OutputDebugString(szPosition);
            772             }
            773         }
            774         else
            775         {
            776             WaitMessage();
            777         }
            778 
            779 NextLoop:
            780         ;
            781     } while (bTerminateThread == FALSE);
            782 
            783     return 0;
            784 }
            由于是新近開發,代碼注釋不多,敬請原諒。
            源碼下載:
             源碼1 源碼2 源碼3

            Feedback

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)[未登錄]  回復  更多評論   

            2010-04-12 11:06 by tina
            一直幫助貓貓測試著播放器,試著一個一個不斷更新的版本,體驗著一個一個不斷增加的新功能,有時候偶爾提出一兩個需求,可以說,見證了播放器的開發過程,見證了貓貓的心血。
            不論怎么說,支持你!加油!

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2010-04-12 15:56 by 欣萌
            用ffmpeg做的播放器。。。
            有技術含量嗎???

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2010-04-12 16:23 by jacky_zz
            非得自己寫解碼器才叫有技術含量?
            Show一個來看看你所謂的技術含量?

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2010-04-13 02:22 by 欲三更
            @欣萌
            難不成您想自己做個ffmpeg?

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2010-04-13 09:23 by 欣萌
            其實不是說你做的不好。
            我平時也用ffmpeg作很多東西,成功之后。總會覺得,真的很失敗。自己做的很少。不過是因為這個庫太強大。

            我是做編解碼器的。所以深刻知道,一個播放器哪里才是最有技術含量的。冒犯到你不好意思啊。

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2010-04-13 09:34 by 萬連文
            1、大音希聲,大道無形,大智之人,不耽于形,不逐于力,不恃于技
            2、用建議的方式而不是批評的方式對待他人的成果,這樣會更好

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2010-04-13 14:30 by jacky_zz
            其實我發布這個程序不是為了吸引網友的眼球,更多的是為了記錄自己在學習過程中的一點心得,以便過了N年后回過頭來看看自己曾經走過的路,我選擇的更多的是默默的去探索,而不愿去更多的爭辯,于事無補。

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2010-04-13 15:53 by 欲三更
            @欣萌
            啊哦, 有眼不識泰山, 真遇到做編解碼器的了...

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2010-04-13 20:34 by 欣萌
            @jacky_zz
            沒想到你居然很在意那條評論。實在對不起。

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2010-04-14 08:28 by jacky_zz
            TO欣萌:沒啊,別人怎么評論那是他的想法,我堅持走自己的路。

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2010-04-14 08:52 by ccsdu2009
            從純技術的觀點說也許使用ffmpeg感覺沒多大挑戰性
            但是從商業角度考慮 能復用別人的東西則更好
            從非流媒體工程師而言 基于這些第三方庫是最好的選擇
            我使用過vlc,ffmpeg

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2010-04-14 10:34 by jacky_zz
            使用什么不重要,而是你能從中得到什么,每個人的側重點不一樣,選擇的方向就不一樣,得到的結果就不一樣,但有一樣是相同的,No Pains, No Gains.

            # CodeProject一識博主,再在二相遇實屬緣分  回復  更多評論   

            2010-08-07 10:50 by hetao.su
            首先說一下我的系統環境,XP SP3+VC6,Ffmpeg編譯環境是SYS+MinGW,采用動態鏈接庫的方式編譯,我采用的是Ffmpeg0.5版本,博主可能是采用0.6吧,avcodec_decode_audio3 0.5版本沒有這個函數,只有avcodec_decode_audio2。輕微修改一下博主的有關,Ffmpeg解碼器的簡單播放器的源代碼,就可以在VC6上編譯運行了,無非就是把修改一下頭文件的一些lib,一些VC9的字符串操作換成VC6的,修改,long long 換成__int64,還有幾個X##LL等等的這些宏定義。對于博主這種分享精神,我表示贊同,本著交流的心態,說一下我的愚見,我想這里存在一些設計的漏洞,如果單純說實現播放音樂,是做到了。但是使用的填充解碼DAUDIO_Write之后采用Sleep這種方式,估計是為了確保lock的時候可以lock在播放光標之前4608byte,不至于覆蓋了播放光標前的數據,同時讓解碼器休息。本人愚見,為什么不采用ds的事件通知機制,雖然DirectSound控制單元來自jdk1.6源碼看似使用很方便,稍稍看了一下他的封裝,在DS_createSoundBuffer創建dsbuffer的時候他只簡單的傳入DSBCAPS_GETCURRENTPOSITION2,DSBCAPS_GLOBALFOCUS兩種參數,也就是說他沒有實現事件通知。為了說明問題,我在創建dsbuffer的函數createSoundBuffer中加入DSBCAPS_CTRLFREQUENCY參數,表示可以修改頻率(播放速度),好啦。然后在MainLoopThreadProc的if(Playing == TRUE && info != NULL)之后也就是真正播放的地方,加個調用info->playBuffer->SetFrequency(2*samplerate);//兩倍速播放。這個時候找個窗體復雜的軟件,不停的最小化和放大它,造成xp的消息隊列比較繁瑣,嘿嘿,效果就出來了。或者再快一點info->playBuffer->SetFrequency(4*samplerate);//四倍 我想肯定不能播放了。完全可以放棄jdk1.6的DS控制單元,自己實現一個DS的操作類,實現通知機制,這樣子就靈活多了。只是實現事件通知的方式,我就不在這里復述,網上多的是例子。

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2010-09-21 17:41 by metaza
            都是牛人

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)[未登錄]  回復  更多評論   

            2010-11-08 16:27 by tj
            您好,可否將您的源代碼給我一份。。。貌似給的源碼壓縮包損壞了。。。謝謝

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)[未登錄]  回復  更多評論   

            2010-11-08 16:28 by tj
            我的郵箱是xiaozhu_tc@yeah.net

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2011-01-15 12:36 by longyaner
            ad as

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2011-03-21 12:16 by ffmpeg
            好像編譯不了,樓主確定嗎

            # re: 基于Ffmpeg解碼器的簡單播放器(a simple audio player based on Ffmpeg)  回復  更多評論   

            2013-03-16 09:04 by 陳阿銘
            TO 欣萌

            真不知道這有什么好炫耀的,又沒有什么好處,做人不能謙虛一點嘛?難道稻米不是親自收成的你就不吃飯啦?
            2021最新久久久视精品爱| 亚洲国产精品无码久久SM | 久久精品国产男包| 久久久av波多野一区二区| 精品乱码久久久久久久| 中文精品久久久久国产网址| 免费国产99久久久香蕉| 久久精品一区二区三区AV| 欧洲成人午夜精品无码区久久| 欧美久久综合九色综合| 久久av无码专区亚洲av桃花岛| 精品久久久久久亚洲| 色妞色综合久久夜夜| 国产无套内射久久久国产| 久久精品国产亚洲av麻豆色欲| 秋霞久久国产精品电影院| 青青久久精品国产免费看| 中文字幕久久亚洲一区| 99精品久久久久久久婷婷| 精品综合久久久久久97| 久久精品成人影院| 99久久99久久精品国产片| 久久www免费人成看片| 久久99精品九九九久久婷婷| 久久精品国产一区二区| 久久精品成人免费看| 日产精品久久久一区二区| 无码乱码观看精品久久| 久久久久国产成人精品亚洲午夜| 国产三级久久久精品麻豆三级| 亚洲日本va中文字幕久久| 国产毛片欧美毛片久久久| 国产激情久久久久影院老熟女免费| 日本人妻丰满熟妇久久久久久| 久久免费视频1| 一本色道久久88精品综合| 午夜精品久久久久久久无码| 久久久久久久国产免费看| 久久精品国产99国产精品| 国产精品综合久久第一页| 久久精品无码一区二区app|