Add: retrieve thumbnail of audio

pull/209/head
xufuji456 3 years ago
parent c9f7a1d058
commit e55bbb5c7a
  1. 2
      app/src/main/cpp/metadata/ffmpeg_media_retriever.c
  2. 1
      app/src/main/cpp/metadata/ffmpeg_media_retriever.h
  3. 6
      app/src/main/cpp/metadata/media_retriever.cpp
  4. 1
      app/src/main/cpp/metadata/media_retriever.h
  5. 31
      app/src/main/cpp/metadata/media_retriever_jni.cpp
  6. 2
      app/src/main/java/com/frank/ffmpeg/activity/ProbeFormatActivity.kt
  7. 11
      app/src/main/java/com/frank/ffmpeg/metadata/FFmpegMediaRetriever.java
  8. 6
      app/src/main/res/layout/activity_probe.xml

@ -487,7 +487,7 @@ void convert_image(State *state, AVCodecContext *pCodecCtx, AVFrame *pFrame, AVP
}
}
int get_embedded_picture(State **state_ptr, AVPacket *pkt) {
int get_audio_thumbnail(State **state_ptr, AVPacket *pkt) {
int i = 0;
int got_packet = 0;
AVFrame *frame = NULL;

@ -54,6 +54,7 @@ int set_data_source_fd(State **ps, int fd, int64_t offset, int64_t length);
const char* extract_metadata(State **ps, const char* key);
int get_frame_at_time(State **ps, int64_t timeUs, int option, AVPacket *pkt);
int get_scaled_frame_at_time(State **ps, int64_t timeUs, int option, AVPacket *pkt, int width, int height);
int get_audio_thumbnail(State **state_ptr, AVPacket *pkt);
int set_native_window(State **ps, ANativeWindow* native_window);
void release(State **ps);

@ -47,6 +47,12 @@ int MediaRetriever::getScaledFrameAtTime(int64_t timeUs, int option, AVPacket *p
return ::get_scaled_frame_at_time(&state, timeUs, option, pkt, width, height);
}
int MediaRetriever::getAudioThumbnail(AVPacket *pkt)
{
Mutex::Autolock lock(mLock);
return ::get_audio_thumbnail(&state, pkt);
}
int MediaRetriever::setNativeWindow(ANativeWindow* native_window)
{
Mutex::Autolock lock(mLock);

@ -30,6 +30,7 @@ public:
const char* extractMetadata(const char* key);
int getFrameAtTime(int64_t timeUs, int option, AVPacket *pkt);
int getScaledFrameAtTime(int64_t timeUs, int option, AVPacket *pkt, int width, int height);
int getAudioThumbnail(AVPacket *pkt);
int setNativeWindow(ANativeWindow* native_window);
private:

@ -260,6 +260,37 @@ RETRIEVER_FUNC(jbyteArray, native_1getScaleFrameAtTime, jlong timeUs, jint optio
return array;
}
RETRIEVER_FUNC(jbyteArray, native_1getAudioThumbnail)
{
MediaRetriever* retriever = getRetriever(env, thiz);
if (retriever == nullptr) {
jniThrowException(env, mIllegalStateException, mNoAvailableMsg);
return nullptr;
}
AVPacket packet;
av_init_packet(&packet);
jbyteArray array = nullptr;
if (retriever->getAudioThumbnail(&packet) == 0) {
int size = packet.size;
uint8_t* data = packet.data;
array = env->NewByteArray(size);
if (!array) {
LOGE(LOG_TAG, "getAudioThumbnail: OutOfMemoryError is thrown.");
} else {
jbyte* bytes = env->GetByteArrayElements(array, nullptr);
if (bytes != nullptr) {
memcpy(bytes, data, size);
env->ReleaseByteArrayElements(array, bytes, 0);
}
}
}
av_packet_unref(&packet);
return array;
}
RETRIEVER_FUNC(void, native_1release)
{
MediaRetriever* retriever = getRetriever(env, thiz);

@ -185,6 +185,8 @@ class ProbeFormatActivity : BaseActivity() {
// Retrieve frame with timeUs
val bitmap = retriever.getFrameAtTime(5 * 1000000)
// Retrieve audio thumbnail, if it has embedded
// val bitmap = retriever.audioThumbnail
if (bitmap != null) {
Log.e("FFmpegRetriever", "bitmap width=${bitmap.width}--height=${bitmap.height}")
mHandler.obtainMessage(MSG_FRAME, bitmap).sendToTarget()

@ -203,6 +203,15 @@ public class FFmpegMediaRetriever {
return getScaledFrameAtTime(timeUs, OPTION_CLOSEST_SYNC, width, height);
}
public Bitmap getAudioThumbnail() {
byte[] picture = native_getAudioThumbnail();
if (picture != null) {
return BitmapFactory.decodeByteArray(picture, 0, picture.length, null);
}
return null;
}
public void release() {
native_release();
}
@ -223,6 +232,8 @@ public class FFmpegMediaRetriever {
private native byte[] native_getScaleFrameAtTime(long timeUs, int option, int width, int height);
private native byte[] native_getAudioThumbnail();
private native void native_release();
/**

@ -13,9 +13,10 @@
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="@string/media_probe"
android:textSize="12sp"
android:textColor="@color/colorPrimary"
android:layout_alignParentStart="true"
android:layout_marginStart="20dp"/>
android:layout_marginStart="10dp"/>
<Button
android:id="@+id/btn_retrieve_format"
@ -23,9 +24,10 @@
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="@string/media_retrieve"
android:textSize="12sp"
android:textColor="@color/colorPrimary"
android:layout_alignParentEnd="true"
android:layout_marginEnd="20dp"/>
android:layout_marginEnd="10dp"/>
<TextView
android:id="@+id/txt_probe_format"

Loading…
Cancel
Save