2015-04-30 20 views
17

Tôi đang sử dụng lớp JavaCV FFmpegFrameRecorder để mã hóa khung xem trước máy ảnh của Android thành video.Đặt siêu dữ liệu luồng video bằng Ffmpeg

Mục tiêu sẽ được nhân rộng kết quả của dòng lệnh sau:

ffmpeg -i input.mp4 -metadata:s:v:0 rotate="90" output.mp4 

tôi sửa đổi phương pháp startUnsafe() như sau, nhưng nó thất bại trong việc tạo ra các đầu ra mong muốn:

if ((video_st = avformat_new_stream(oc, video_codec)) != null) { 
     video_c = video_st.codec(); 
     video_c.codec_id(oformat.video_codec()); 
     video_c.codec_type(AVMEDIA_TYPE_VIDEO); 
     ... 
     AVDictionary avDictionary = new AVDictionary(null); 
     av_dict_set(avDictionary, "rotate", "90", 0); 
     video_st.metadata(avDictionaty); 
     ... 
} 
... 
avformat_write_header(oc, (PointerPointer) null); 

này vẫn mã hóa video chính xác, nhưng siêu dữ liệu được thêm vào không bao giờ xuất hiện trên ffprobe. Nếu nó giúp, mã hóa video là h264.

Bằng cách này, đây là đầu ra ffprobe:

ffprobe version 2.3.3 Copyright (c) 2007-2014 the FFmpeg developers 
    built on Jan 22 2015 18:22:57 with Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn) 
    configuration: --prefix=/usr/local/Cellar/ffmpeg/2.3.3 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-nonfree --enable-hardcoded-tables --enable-avresample --enable-vda --cc=clang --host-cflags= --host-ldflags= --enable-libx264 --enable-libfaac --enable-libmp3lame --enable-libxvid --enable-libfreetype --enable-libvorbis --enable-libvpx --enable-libass --enable-ffplay --enable-libfdk-aac --enable-libopus --enable-libquvi --enable-libx265 
    libavutil  52. 92.100/52. 92.100 
    libavcodec  55. 69.100/55. 69.100 
    libavformat 55. 48.100/55. 48.100 
    libavdevice 55. 13.102/55. 13.102 
    libavfilter  4. 11.100/4. 11.100 
    libavresample 1. 3. 0/1. 3. 0 
    libswscale  2. 6.100/2. 6.100 
    libswresample 0. 19.100/0. 19.100 
    libpostproc 52. 3.100/52. 3.100 
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'abcd.mp4': 
    Metadata: 
    major_brand  : isom 
    minor_version : 512 
    compatible_brands: isomiso2avc1mp41 
    encoder   : Lavf56.15.102 
    Duration: 00:00:19.48, start: 0.023220, bitrate: 572 kb/s 
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1/0x31637661), yuv420p, 1280x720, 573 kb/s, 5.71 fps, 30 tbr, 15360 tbn, 60 tbc (default) 
    Metadata: 
     handler_name : VideoHandler 
    Stream #0:1(und): Audio: aac (mp4a/0x6134706D), 44100 Hz, mono, fltp, 64 kb/s (default) 
    Metadata: 
     handler_name : SoundHandler 

Mọi góp ý về lý do tại sao nó được không? Cảm ơn.

+0

Câu hỏi tương tự: http://stackoverflow.com/questions/17024192/how-to-set-header-metadata-to-encoded-video –

Trả lời

1

FFmpegFrameRecorderclass bạn đang sử dụng sử dụng AVFormatContextclass. Xung quanh dòng 2579 bạn có thể nhìn thấy từ chữ ký phương pháp, rằng lớp AVFormatContext sử dụng mã nguồn gốc từ thực hiện cả hai

  • public native AVDictionary metadata() phương pháp phương pháp
  • public native AVFormatContext metadata(AVDictionary metadata).

Câu trả lời cho liên kết bạn cung cấp cho biết họ đã sử dụng thuộc tính metadata trực tiếp AVFormatContext - giống như phương pháp đầu tiên tôi nghĩ. Nhưng Line 649 của FFmpegFrameRecorder sử dụng phương pháp thứ hai - tôi nghi ngờ. ví dụ:

AVDictionary metadata = new AVDictionary(null); 
... code to fill up dictionary ... 
... 

avformat_write_header(oc.metadata(metadata), options); 

Đáng tiếc là tôi không thể thử điều này vào lúc này, nhưng tôi tự hỏi, nếu bạn có thể làm một cái gì đó như thế này:

AVDictionary metadata = co.metadata(); 
... code to fill up dictionary ... 

//I would assume at this point that oc has the metadata so 
avformat_write_header(oc, (PointerPointer) null); 
//if not then maybe 
// avformat_write_header(oc.metadata(metadata), options); 

Chữ ký cho thấy nó là công khai, vì vậy tôi không xem tại sao bạn không thể tải từ điển siêu dữ liệu từ số trực tiếp AVFormatContext. Tôi không chắc phương thức avformat_write_header hoạt động như thế nào, vì vậy tôi đã đề xuất hai điều trên.

Lưu ý: Tôi có không đã sử dụng thư viện này trước đây. Tôi đã thử, không thành công để sử dụng Xuggler trong quá khứ đối với một số mã hóa cơ bản.

4

Dường như câu hỏi này tạo ra nhiều sự quan tâm vì vậy tôi đang thêm một số thông tin khác. Sau đây GitHub issue Samuel từ JavaCV committed một số thay đổi để cho phép truy cập dễ dàng hơn vào cài đặt siêu dữ liệu.

Thiết metadata có thể đạt được thông qua các đoạn mã sau:

AVDictionary metadata = new AVDictionary(null); 
for (Entry<String, String> e : videoMetadata.entrySet()) { 
    av_dict_set(metadata, e.getKey(), e.getValue(), 0); 
} 
video_st.metadata(metadata); 

Bạn có thể kích hoạt nó ngay bây giờ bằng cách làm mvn install -Pffmpeg hoặc chờ cho đến khi việc phát hành JavacV tới, mà nên là 0,12.

PS: Như bạn có thể thấy, điều này khá giống với những gì tôi đã trình bày trong câu hỏi của mình, vì vậy tôi không chắc chắn tại sao nó không hoạt động ngay từ đầu.

Các vấn đề liên quan