当前位置:首页 » 安卓系统 » androidffmpeg播放

androidffmpeg播放

发布时间: 2022-07-12 02:10:43

‘壹’ 如何在Android用FFmpeg解码图像

创建一个VideoPicture结构体用来保存解码出来的图像。

LOCAL_PATH := $(call my-dir)
###########################
#
# SDL shared library
#
###########################
include $(CLEAR_VARS)
LOCAL_MODULE := SDL2
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
LOCAL_SRC_FILES := \
$(subst $(LOCAL_PATH)/,, \
$(wildcard $(LOCAL_PATH)/src/*.c) \
$(wildcard $(LOCAL_PATH)/src/audio/*.c) \
$(wildcard $(LOCAL_PATH)/src/audio/android/*.c) \
$(wildcard $(LOCAL_PATH)/src/audio/mmy/*.c) \
$(LOCAL_PATH)/src/atomic/SDL_atomic.c \
$(LOCAL_PATH)/src/atomic/SDL_spinlock.c.arm \
$(wildcard $(LOCAL_PATH)/src/core/android/*.c) \
$(wildcard $(LOCAL_PATH)/src/cpuinfo/*.c) \
$(wildcard $(LOCAL_PATH)/src/dynapi/*.c) \
$(wildcard $(LOCAL_PATH)/src/events/*.c) \
$(wildcard $(LOCAL_PATH)/src/file/*.c) \
$(wildcard $(LOCAL_PATH)/src/haptic/*.c) \
$(wildcard $(LOCAL_PATH)/src/haptic/mmy/*.c) \
$(wildcard $(LOCAL_PATH)/src/joystick/*.c) \
$(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \
$(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c) \
$(wildcard $(LOCAL_PATH)/src/power/*.c) \
$(wildcard $(LOCAL_PATH)/src/power/android/*.c) \
$(wildcard $(LOCAL_PATH)/src/filesystem/mmy/*.c) \
$(wildcard $(LOCAL_PATH)/src/render/*.c) \
$(wildcard $(LOCAL_PATH)/src/render/*/*.c) \
$(wildcard $(LOCAL_PATH)/src/stdlib/*.c) \
$(wildcard $(LOCAL_PATH)/src/thread/*.c) \
$(wildcard $(LOCAL_PATH)/src/thread/pthread/*.c) \
$(wildcard $(LOCAL_PATH)/src/timer/*.c) \
$(wildcard $(LOCAL_PATH)/src/timer/unix/*.c) \
$(wildcard $(LOCAL_PATH)/src/video/*.c) \
$(wildcard $(LOCAL_PATH)/src/video/android/*.c) \
$(wildcard $(LOCAL_PATH)/src/test/*.c))
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES
LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -llog -landroid
include $(BUILD_SHARED_LIBRARY)
###########################
#
# SDL static library
#
###########################
#LOCAL_MODULE := SDL2_static
#LOCAL_MODULE_FILENAME := libSDL2
#LOCAL_SRC_FILES += $(LOCAL_PATH)/src/main/android/SDL_android_main.c
#LOCAL_LDLIBS :=
#LOCAL_EXPORT_LDLIBS := -Wl,--undefined=java_org_libsdl_app_SDLActivity_nativeInit -ldl -lGLESv1_CM -lGLESv2 -llog -landroid
#include $(BUILD_STATIC_LIBRARY)

二、参考[原]如何在Android用FFmpeg解码图像, 在工程中新建一个ffmpeg文件夹,将与ffmpeg相关的头文件include进来。ffmpeg文件夹下的Android.mk内容:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg
LOCAL_SRC_FILES := /path/to/build/ffmpeg/libffmpeg.so
include $(PREBUILT_SHARED_LIBRARY)

三、新建player文件夹,用来编写解码与显示文件。player.c文件内容:

/*
* SDL_Lesson.c
*
* Created on: Aug 12, 2014
* Author: clarck
*/
#include <jni.h>
#include <android/native_window_jni.h>
#include "SDL.h"
#include "SDL_thread.h"
#include "SDL_events.h"
#include "../include/logger.h"
#include "../ffmpeg/include/libavcodec/avcodec.h"
#include "../ffmpeg/include/libavformat/avformat.h"
#include "../ffmpeg/include/libavutil/pixfmt.h"
#include "../ffmpeg/include/libswscale/swscale.h"
int main(int argc, char *argv[]) {
char *file_path = argv[1];
LOGI("file_path:%s", file_path);
AVFormatContext *pFormatCtx;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame, *pFrameYUV;
AVPacket *packet;
uint8_t *out_buffer;
SDL_Texture *bmp = NULL;
SDL_Window *screen = NULL;
SDL_Rect rect;
SDL_Event event;
static struct SwsContext *img_convert_ctx;
int videoStream, i, numBytes;
int ret, got_picture;
av_register_all();
pFormatCtx = avformat_alloc_context();
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
LOGE("Could not initialize SDL - %s. \n", SDL_GetError());
exit(1);
}
if (avformat_open_input(&pFormatCtx, file_path, NULL, NULL) != 0) {
LOGE("can't open the file. \n");
return -1;
}
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
LOGE("Could't find stream infomation.\n");
return -1;
}
videoStream = 1;
for (i = 0; i < pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStream = i;
}
}
LOGI("videoStream:%d", videoStream);
if (videoStream == -1) {
LOGE("Didn't find a video stream.\n");
return -1;
}
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
LOGE("Codec not found.\n");
return -1;
}
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
LOGE("Could not open codec.\n");
return -1;
}
pFrame = av_frame_alloc();
pFrameYUV = av_frame_alloc();
//---------------------------init sdl---------------------------//
screen = SDL_CreateWindow("My Player Window", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, pCodecCtx->width, pCodecCtx->height,
SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
SDL_Renderer *renderer = SDL_CreateRenderer(screen, -1, 0);
bmp = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12,
SDL_TEXTUREACCESS_STREAMING, pCodecCtx->width, pCodecCtx->height);
//-------------------------------------------------------------//

img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,
pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height,
AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
numBytes = avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width,
pCodecCtx->height);
out_buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
avpicture_fill((AVPicture *) pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P,
pCodecCtx->width, pCodecCtx->height);
rect.x = 0;
rect.y = 0;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;
int y_size = pCodecCtx->width * pCodecCtx->height;
packet = (AVPacket *) malloc(sizeof(AVPacket));
av_new_packet(packet, y_size);
av_mp_format(pFormatCtx, 0, file_path, 0);
while (av_read_frame(pFormatCtx, packet) >= 0) {
if (packet->stream_index == videoStream) {
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture,
packet);
if (ret < 0) {
LOGE("decode error.\n");
return -1;
}
LOGI("got_picture:%d", got_picture);
if (got_picture) {
sws_scale(img_convert_ctx,
(uint8_t const * const *) pFrame->data,
pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data,
pFrameYUV->linesize);
////iPitch 计算yuv一行数据占的字节数
SDL_UpdateTexture(bmp, &rect, pFrameYUV->data[0], pFrameYUV->linesize[0]);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, bmp, &rect, &rect);
SDL_RenderPresent(renderer);
}
SDL_Delay(50);
}
av_free_packet(packet);
SDL_PollEvent(&event);
switch (event.type) {
case SDL_QUIT:
SDL_Quit();
exit(0);
break;
default:
break;
}

‘贰’ 如何在Android用FFmpeg+SDL2.0解码显示图像

关于如何在Android上用FFmpeg+SDL2.0解码显示图像参考[原]如何在Android用FFmpeg+SDL2.0解码显示图像 ,关于如何在Android使用FFmpeg+SDL2.0解码声音参考[原]如何在Android用FFmpeg+SDL2.0解码声音。但是该文章有一个问题,就是解码出来的声音有很大的噪音,基本无法听清,这是由于对于声音的处理有问题。故本文参考ffmpeg-sdl音频播放分析声音解码的处理,解码出来的声音就正常了。
博主的开发环境:Ubuntu 14.04 64位,Eclipse+CDT+ADT+NDK。
在文章开始之前假定你已经知道如何使用NDK编译FFmpeg,以及知道如何移植SDL2.0到Android平台上来并且知道如何解码显示图像和声音了。
我们初步了解如何解码视频图像和视频声音。但是这些都是初步简单的解码出来而已,我们的主要功能是处理非常多:它是通过事件循环中运行,读取数据包,并在视频解码。所以,我们要做的就是拆分这些功能:我们将有一个线程,该线程将负责数据包进行解码;这些数据包将被添加到该队列中,并通过相应的音频和视频解码线程读取。
音频线:我们在[原]如何在Android用FFmpeg+SDL2.0解码声音这篇文章里面有了一个初步的音频线模型,在本文我们继续去完善这个;
视频线:频线会相对比较麻烦一些,因为我们要自己显示自己的视频画面。我们将实际实现的代码添加到主循环。我们的想法是对视频进行解码,保存生成到一个队列中,然后创建一个自定义刷新事件(FF_REFRESH_EVENT),我们添加它到事件系统中,那么当我们的事件循环看到这种情况,它会显示在队列的下一帧中,这样一边解码一边显示。
工程中的目录结构和[原]如何在Android用FFmpeg+SDL2.0解码声音 一样,只是在其基础上继续添加功能。
一、创建一个VideoPicture结构体用来保存解码出来的图像。
二、添加数据队列的初始化、添加以及读取的函数。
三、audio_decode_frame():解码音频
四、audio_callback(): 回调函数,向SDL缓冲区填充数据
五、创建视频刷新相关的函数:
schele_refresh():它主要的作用是告诉系统指定的毫秒数后推FF_REFRESH_EVENT。当我们看到它在事件队列时,将依次调用视频刷新功能。
六、添加视频显示函数:
因为我们的屏幕可以是任意大小(我们设定我们为640×480,并有一些方法来设置它,所以它是由用户调整大小),我们需要动态地计算出我们有多大的矩形。因此,首先我们需要弄清楚我们的电影的显示比例,这仅仅是宽度除以身高。某些编解码器将有一个奇怪的样本纵横比,这就是一个像素,或样品的宽度/高度。因为在我们的编解码器的上下文中的高度和宽度值以像素为单位测量,实际的宽高比等于宽高比数倍的样品长宽比。一些编解码器将显示0-5的宽高比,这表示每个像素仅仅是大小1x1的。然后,我们扩展了电影,以适应在我们的屏幕上。
七、分配显示输出内存空间:
使用队列中,我们有两个指针 - 写入索引和阅读索引。我们还跟踪实际的照片有多少是在缓冲区中。要写入队列中,我们将首先等待我们的缓冲清除,所以我们足够的空间来存储我们VideoPicture。然后我们检查,看看是否已经分配了覆盖在我们的写作索引。如果没有,我们就必须分配一定的空间。如果窗口的大小发生了变化, 我们也要重新分配缓冲区。
八、解码线程,将解码器,建立音频线,保存重要信息到数据结构中。
九、编写Main函数用来调用解码线程。

‘叁’ android 中使用ffmpeg,将视频加入字幕,用ass文件,在PC上可以,但在Android上一直不行

理论上来讲:任何视频格式都是支持外挂字幕的 迅雷看看也是支持外挂字幕的 没显示字幕的可能性有两个: 1、播放器不支持外挂字幕(显然应该不是播放器的问题,有可能你关闭了外挂字幕功能,你可以试着重新安装迅雷看看) 2、视频文件名跟字幕文件名不同(在同一个文件夹下要播放器自动载入外挂字幕,首先必须保证视频跟字幕在同一个文件夹内,然后要保证文件名称一样,这里说的文件名称不包括后缀名 举个例子: 视频文件名为:ZXCV.mp4 ,,这里我们可以看到这个视频是一个名称为:ZXCV的MP4格式的视频文件,ZXCV为为视频名称,“.mp4”则为文件的后缀名,即为文件种类 要保证外挂字幕文件顺利的自动载入,那么它的文件名就必须为:“ZXCV.ass”) 明白?

‘肆’ 如何在Android用FFmpeg+SDL2.0之同步音频

一、创建一个VideoPicture结构体用来保存解码出来的图像。
二、添加数据队列的初始化、添加以及读取的函数。
三、audio_decode_frame():解码音频
四、audio_callback(): 回调函数,向SDL缓冲区填充数据
五、创建视频刷新相关的函数:
schele_refresh():它主要的作用是告诉系统指定的毫秒数后推FF_REFRESH_EVENT。当我们看到它在事件队列时,将依次调用视频刷新功能。
六、添加视频显示函数:
因为我们的屏幕可以是任意大小(我们设定我们为640×480,并有一些方法来设置它,所以它是由用户调整大小),我们需要动态地计算出我们有多大的矩形。因此,首先我们需要弄清楚我们的电影的显示比例,这仅仅是宽度除以身高。某些编解码器将有一个奇怪的样本纵横比,这就是一个像素,或样品的宽度/高度。因为在我们的编解码器的上下文中的高度和宽度值以像素为单位测量,实际的宽高比等于宽高比数倍的样品长宽比。一些编解码器将显示0-5的宽高比,这表示每个像素仅仅是大小1x1的。然后,我们扩展了电影,以适应在我们的屏幕上。
七、分配显示输出内存空间:
使用队列中,我们有两个指针 - 写入索引和阅读索引。我们还跟踪实际的照片有多少是在缓冲区中。要写入队列中,我们将首先等待我们的缓冲清除,所以我们足够的空间来存储我们VideoPicture。然后我们检查,看看是否已经分配了覆盖在我们的写作索引。如果没有,我们就必须分配一定的空间。如果窗口的大小发生了变化, 我们也要重新分配缓冲区。
八、解码线程,将解码器,建立音频线,保存重要信息到数据结构中。
九、编写Main函数用来调用解码线程。

‘伍’ 哪位高人知道FFmpeg在android平台下如何应用

这个可以看c与java的传递数据那一方面的内容,你可以在java端写一个native方法,传入转码命令,在jni写代码接收命令,分析命令

‘陆’ android ffmpeg 是啥意思

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。
用来开发音视频的~!

‘柒’ android-ffmpeg-x264 怎么用

Android内置的编解码器实在太少,于是我们需要FFmpeg。Android提供了NDK,为我们使用FFmpeg这种C语言代码提供了方便。
不过为了用NDK编译FFmpeg,还真的花费了不少时间,也得到了很多人的帮助,最应该谢谢havlenapetr。我觉得我现在这些方法算是比较简洁的了--
下面就尽量详细的说一下我是怎么在项目中使用FFmpeg的,但是基于我混乱的表达能力,有不明白的就问我。
你得了解JNI和Android NDK的基本用法,若觉得我的文章还不错,可以看之前写的JNI简单入门和Android NDK入门
首先创建一个标准的Android项目vPlayer
android create project -n vPlayer -t 8 -p vPlayer -k me.abitno.vplayer -a PlayerView
然后在vPlayer目录里
mkdir jni && cd jni
wget http://ffmpeg.org/releases/ffmpeg-0.6.tar.bz2
tar xf ffmpeg-0.6.tar.bz2 && mv ffmpeg-0.6 ffmpeg && cd ffmpeg
在ffmpeg下新建一个config.sh,内容如下,注意把PREBUILT和PLATFORM设置正确。另外里面有些参数你也可以自行调整,我主要是为了配置一个播放器而这样设置的。
#!/bin/bash

PREBUILT=/home/abitno/Android/android-ndk-r4/build/prebuilt/linux-x86/arm-eabi-4.4.0
PLATFORM=/home/abitno/Android/android-ndk-r4/build/platforms/android-8/arch-arm

./configure --target-os=linux \
--arch=arm \
--enable-version3 \
--enable-gpl \
--enable-nonfree \
--disable-stripping \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffserver \
--disable-ffprobe \
--disable-encoders \
--disable-muxers \
--disable-devices \
--disable-protocols \
--enable-protocol=file \
--enable-avfilter \
--disable-network \
--disable-mpegaudio-hp \
--disable-avdevice \
--enable-cross-compile \
--cc=$PREBUILT/bin/arm-eabi-gcc \
--cross-prefix=$PREBUILT/bin/arm-eabi- \
--nm=$PREBUILT/bin/arm-eabi-nm \
--extra-cflags="-fPIC -DANDROID" \
--disable-asm \
--enable-neon \
--enable-armv5te \
--extra-ldflags="-Wl,-T,$PREBUILT/arm-eabi/lib/ldscripts/armelf.x -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtbegin.o $PREBUILT/lib/gcc/arm-eabi/4.4.0/crtend.o -lc -lm -ldl"
运行config.sh开始configure
chmod +x config.sh
./config.sh
configure完成后,编辑刚刚生成的config.h,找到这句
#define restrict restrict
Android的GCC不支持restrict关键字,于是修改成下面这样
#define restrict
编辑libavutil/libm.h,把其中的static方法都删除。

‘捌’ 怎么利用ffmpeg实现android播放器

下面把具体编译步骤描述如下,假定NDK安装在~/android-ndk-r7:
1. 首先从FFmpeg官网下载最新的release版本源码ffmpeg-0.11.tar.gz解压缩到Android源码树的ffmpeg/下。
2 准备一个编译脚本build_android.sh并放在ffmpeg/下面,这个脚本也是Rockplayer提供的,需做一些修改,其内容附在后面。我目前用的也会附在后面。
3 在ffmpeg目录下运行./build_android.sh开始编译FFmpeg,编译好的libffmpeg.so会放在文件夹android里面,一共有3个版本分别对应3种ARM体系结构,包括armv7-a、armv7-a-vfp、armv6_vfp,根据所运行的硬件平台选取其中一个版本。为了编译使用FFmpeg的程序时可以方便地找到libffmpeg.so,可将它复制到$OUT/system/lib/和$OUT/obj/lib/,当然这一步也可以加在build_android.sh中做。
4. 接下来就是编译可执行文件ffmpeg了,这个工具可以在命令行下完成FFmpeg提供的几乎所有功能包括编码、解码、转码等,也是用来调试和验证很有用的工具。其实上述编译完后在$ANDROID_BUILD_TOP/external/ffmpeg/下也会生成ffmpeg,但是在设备上无法运行。为了编出能在设备上运行的ffmpeg,可以写一个简单的Android.mk,

‘玖’ 如何在Android用FFmpeg+SDL2.0解码声音

一、创建一个VideoPicture结构体用来保存解码出来的图像;
二、添加数据队列的初始化、添加以及读取的函数;
三、audio_decode_frame():解码音频;
四、audio_callback(): 回调函数,向SDL缓冲区填充数据;
五、创建视频刷新相关的函数;
六、添加视频显示函数;
七、分配显示输出内存空间;
八、解码线程,将解码器,建立音频线,保存重要信息到数据结构中;
九、编写Main函数用来调用解码线程。
知识点延伸:
FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件)。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多codec都是从头开发的。FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行。
SDL2.0(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。SDL内置了调用OpenGL的函数。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。

热点内容
dz上传的图片不显示 发布:2025-01-28 09:37:42 浏览:887
joinsql多表 发布:2025-01-28 09:23:26 浏览:729
php数组循环赋值 发布:2025-01-28 09:23:25 浏览:134
android42系统 发布:2025-01-28 09:21:59 浏览:902
菜单设计c语言 发布:2025-01-28 09:21:54 浏览:274
sql多表查询优化 发布:2025-01-28 09:21:05 浏览:503
iphone6便捷访问 发布:2025-01-28 09:05:11 浏览:177
四位验证密码是多少 发布:2025-01-28 08:56:13 浏览:809
笔记本显卡如何配置 发布:2025-01-28 08:49:49 浏览:603
为什么安卓会有卸载残留 发布:2025-01-28 08:32:00 浏览:89