Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Trang 1 của 2 12 CuốiCuối
Kết quả 1 đến 10 của 18
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    sử dụng ffmpeg để lập trình với android?

    Hi all, như tiêu đề mình đưa, có bạn nào đã triển khai, nghiên cứu tìm hiểu để làm chương trình mà sử dụng tool ( thư viện ) ffmpeg để xử lý audio và video với android chưa? Hiện tại mình mới chỉ dừng lại ở mức build và chạy demo 1 ứng dụng nhỏ, nhưng do kiến thức còn hạn chế nhiều, mà code cái này đòi hỏi lập trình C , JNI. Cụ thể ví dụ với việc convert 1 file .avi sang .wav nếu code trong android sẽ làm như nào? Bạn nào biết giúp mình với.
    Hiện tại ngoài việc sử dụng terminal để chạy câu lệnh: ví dụ: ffmpeg -i test.avi , thực hiện rất đơn giản, vậy làm sao để chuyển tương ứng vào trong android, đó chính là vấn đề mình muốn đề cập tới.

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Mình chưa thử với Android, tuy nhiên khi xưa mình dùng OpenCV, nó cho tương tác với một frame rất dễ dàng. Và OpenCV is very fast and cross-platform. Nhân trong Android là Linux, bạn thử build một version nào đó rồi tìm cách dùng nó thử xem sao?
    http://opencv.willowgarage.com/wiki/

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Bản thân bên trong thằng OpenCV này là ffmpeg. OpenCV cũng khá là nặng vì vậy mình được tìm hiểu ffmpeg. Không biết bạn rox_rook đã lập trình sử dụng JNI chưa?. Về nguyên tắc thì việc lấy frame trong video được hiểu như nào vậy bạn?

  4. #4
    Trích dẫn Gửi bởi snake_programmer
    Bản thân bên trong thằng OpenCV này là ffmpeg. OpenCV cũng khá là nặng vì vậy mình được tìm hiểu ffmpeg. Không biết bạn rox_rook đã lập trình sử dụng JNI chưa?. Về nguyên tắc thì việc lấy frame trong video được hiểu như nào vậy bạn?
    1 file video được chia thành các strem (có thể là video stream, audio strem, sub title ...), một stream có thể được mã hóa bởi 1 codec nào đó, ffmpeg cho phép tự động phân tích để lựa chọn codec thích hợp cho stream đó. Với codec này, bạn có thể trích ra frame bất ký.

    Đây là tut của ffmpeg: http://dranger.com/ffmpeg/tutorial01.html

    Code trên kia dành cho phiên bản cũ của ffmpeg nên có nhiều hàm đã bị bỏ và thay bằng hàm khác, đây là code mình đã sửa lại:

    Mã:
    // avcodec_sample.0.4.9.cpp // A small sample program that shows how to use libavformat and libavcodec to// read video from a file.//// This version is for the 0.4.9-pre1 release of ffmpeg. This release adds the// av_read_frame() API call, which simplifies the reading of video frames // considerably. //// Use//// g++ -o avcodec_sample.0.4.9 avcodec_sample.0.4.9.cpp -lavformat -lavcodec \//     -lz//// to build (assuming libavformat and libavcodec are correctly installed on// your system).//// Run using//// avcodec_sample.0.4.9 myvideofile.mpg//// to write the first five frames from "myvideofile.mpg" to disk in PPM// format. #ifdef __cplusplusextern "C" {#endif#include <libavcodec/avcodec.h>#include <libavformat/avformat.h>#include <libswscale/swscale.h>#ifdef __cplusplus}#endif #include <stdio.h> void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame){    FILE *pFile;    char szFilename[32];    int  y;     // Open file    sprintf(szFilename, "frame%d.ppm", iFrame);    pFile=fopen(szFilename, "wb");    if(pFile==NULL)        return;     // Write header    fprintf(pFile, "P6
    %d %d
    255
    ", width, height);     // Write pixel data    for(y=0; y<height; y++)        fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);     // Close file    fclose(pFile);} int main(int argc, char *argv[]){    AVFormatContext *pFormatCtx;    int             i, videoStream;    AVCodecContext  *pCodecCtx;    AVCodec         *pCodec;    AVFrame         *pFrame;     AVFrame         *pFrameRGB;    AVPacket        packet;    SwsContext      *pSWSCtx;      int             frameFinished;    int             numBytes;    uint8_t         *buffer;     // Register all formats and codecs    av_register_all();     // Open video file    pFormatCtx = avformat_alloc_context();    if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)        return -1; // Couldn't open file     // Retrieve stream information    if(avformat_find_stream_info(pFormatCtx, NULL)<0)        return -1; // Couldn't find stream information     // Dump information about file onto standard error    av_dump_format(pFormatCtx, 0, argv[1], false);     // Find the first video stream    videoStream=-1;    for(i=0; i<pFormatCtx->nb_streams; i++)        if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)        {            videoStream=i;            break;        }    if(videoStream==-1)        return -1; // Didn't find a video stream     // Get a pointer to the codec context for the video stream    pCodecCtx=pFormatCtx->streams[videoStream]->codec;     // Find the decoder for the video stream    pCodec=avcodec_find_decoder(pCodecCtx->codec_id);    if(pCodec==NULL)        return -1; // Codec not found     // Open codec    if(avcodec_open2(pCodecCtx, pCodec, NULL)<0)        return -1; // Could not open codec     // Hack to correct wrong frame rates that seem to be generated by some     // codecs    // if(pCodecCtx->frame_rate>1000 && pCodecCtx->frame_rate_base==1)    //    pCodecCtx->frame_rate_base=1000;     // Allocate video frame    pFrame=avcodec_alloc_frame();     // Allocate an AVFrame structure    pFrameRGB=avcodec_alloc_frame();    if(pFrameRGB==NULL)        return -1;     // Determine required buffer size and allocate buffer    numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,        pCodecCtx->height);    buffer=new uint8_t[numBytes];     // Assign appropriate parts of buffer to image planes in pFrameRGB    avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,        pCodecCtx->width, pCodecCtx->height);     // Initialize Sws context    pSWSCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height,             pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height,            PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);     // Read frames and save first five frames to disk    i=0;    while(av_read_frame(pFormatCtx, &packet)>=0)    {        // Is this a packet from the video stream?        if(packet.stream_index==videoStream)        {            // Decode video frame            avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);              // Did we get a video frame?            if(frameFinished)            {                // Convert the image from its native format to RGB//                img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24, //                    (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, //                    pCodecCtx->height);                sws_scale(pSWSCtx, pFrame->data, pFrame->linesize, 0,                        pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);                 // Save the frame to disk                if(++i<=5)                    SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height,                         i);            }        }         // Free the packet that was allocated by av_read_frame        av_free_packet(&packet);    }     // free sws context    sws_freeContext(pSWSCtx);     // Free the RGB image    delete [] buffer;    av_free(pFrameRGB);     // Free the YUV frame    av_free(pFrame);     // Close the codec    avcodec_close(pCodecCtx);     // Close the video file    avformat_free_context(pFormatCtx);    avformat_close_input(&pFormatCtx);     return 0;}
    Chương trình này lấy 5 frame của video và chuyển nó thành ảnh bitmap. Bạn có thể thu lại thành 1 hàm và gọi nó qua JNI.

    -------------------------------------------------------------------------------

    Vừa google được cái tutor về ffmpeg cho Android: http://www.roman10.net/how-to-build-...by-an-example/

  5. #5
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Cảm ơn bạn boss14420 nhiều, mình có đọc qua tutorial đó, nhưng nó quá mới so với mình nhất là JNI. Mình có một thắc mắc là với code viết bằng C trên, hàm SaveFrame đó nếu mình truyền vào fileName nằm trong thư mục mnt/sdcard của Device thì liệu có xuất ra được thành file ảnh trong đó không? ( Cơ chế của JNI mình vẫn chưa hiểu rõ lắm ).
    Hiện tại mình đang code dùng IDE Eclipse, khi tích hợp C/C++ vào thì format rất xấu, code không xuất hiện gợi ý các hàm ( Mặc dù include chuẩn rồi ). Mình muốn code như thằng C-Free hay Eclipse bản C/C++ phải làm như nào nhỉ?

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Nếu làm như vậy thì rất dễ bị lỗi...![IMG]images/smiliesot_talking.gif[/IMG]

  7. #7
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Làm sao để mình có thể lấy được 1 frame bất kỳ trong video các bạn nhỉ? Sử dụng ffmpeg, hay cho mình ý tưởng cũng được. . Mình không thạo JNI, Muốn trả về một Bitmap? một int như thế nào đây?

  8. #8
    Trích dẫn Gửi bởi snake_programmer
    Làm như thế nào thì không bị lỗi hả bạn? Mình lấy code trên vào dùng NDK để build nhưng gặp một vài lỗi và không build được.
    Lỗi gì ?
    code của mình là dành cho ffmpeg 1:0.11.1-1, nếu không đúng bản thì có thể có một số lỗi không tương thích.

  9. #9
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Mình đã fix được code trên và đưa vào project, tuy nhiên lại gặp một lỗi là hàm: avcodec_find_encoder(codec_id) luôn trả về NULL nên mình không thể save AVFrame thành file .jpeg được.

  10. #10
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Code trên là find_decoder chứ có phải find_encoder đâu ?

 

 
Trang 1 của 2 12 CuốiCuối

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •