android开发之音视频(二)

【Android 音视频开发打怪升级:音视频硬解码篇】二、音视频硬解码流程:封装基础解码框架 为了方便记录解码状态,这里使用一个枚举类表示/*开始状态START,/*解码中DECODING,/*解码暂停PAUSE,/*正在快进SEEKING,/*解码完成FINISH,/*解码器释放STOP前面说过,MediaCodec需要我们不断地喂数据给输入缓冲,那么数据从哪里来呢?肯定是音视频文件了,这里的IExtractor就是用来提取音视频文件中数据流。 阅读详情

转载请标明出处:
http://blog.youkuaiyun.com/AnalyzeSystem/article/details/79311530
本文出自Analyzesystem的博客

我且把视频开发大致分为视频显示控件和音视频控制控件、弹窗控件

  • MediaPlayer

  • MediaController

  • Popu


height="230" width="130" src="https://img-blog.youkuaiyun.com/20180211163401355?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQW5hbHl6ZVN5c3RlbQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast">

播放器MediaPlayer可以理解为一个容器,容纳多种布局,这里布局按照16:9的比例显示画面,摆在博主面前的第一个难题出现了,如何实现小屏和全屏的无缝切换?网上有诸多方案并不能令博主满意,最后在几经尝试以及一位博友提示下想到了一个方案

修改MediaPlayer onMeasure函数,根据不同的模式动态requestLayout 动态调整控件宽高,同时回调函数通知隐藏状态栏和标题栏(不一定是标题栏,所以回调函数自己控制)

Tip:
一定要注意修改manifest文件 android:configChanges="screenSize|keyboardHidden|orientation",这样横竖屏切换不会走生命周期,只会changed回调

下面是伪类代码块

package idea.analyzesystem.ijkplayer.widget;

import android.content.Context;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;

import idea.analyzesystem.ijkplayer.interfaces.MediaPlayerListener;

/**
 * Created by idea on 2018/2/11.
 */
public class MediaPlayer extends FrameLayout implements View.OnClickListener{

    private final Point screenPoint;

    public static final int MODE_LANDSCAPE = 0;

    public static final int MODE_PORTRAITSCREEN = 1;

    private int mode = MODE_PORTRAITSCREEN;

    public int getMode() {
        return mode;
    }

    /**
     *  MODE_LANDSCAPE 、MODE_PORTRAITSCREEN
     * @param mode
     */
    public void setMode(int mode) {
        if(this.mode!=mode){
            this.mode = mode;
            switch (getMode()){
                case MODE_LANDSCAPE:
                    if(getScreenChangedListener()!=null){
                        getScreenChangedListener().onLandScape();
                    }
                    requestLayout();
                    break;

                case MODE_PORTRAITSCREEN:
                    if(getScreenChangedListener()!=null){
                        getScreenChangedListener().onPortailScreen();
                    }
                    requestLayout();
                    break;
            }
        }

    }

    public MediaPlayer(Context context) {
        this(context,null,0);
    }

    public MediaPlayer(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MediaPlayer(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        screenPoint = new Point();
        windowManager.getDefaultDisplay().getSize(screenPoint);

        setOnClickListener(this);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        switch (getMode()){
            case MODE_LANDSCAPE:
                setMeasuredDimension(screenPoint.y,screenPoint.x);
                break;

            case MODE_PORTRAITSCREEN:

                setMeasuredDimension(screenPoint.x,screenPoint.x/16*9);
                break;
        }
    }


    @Override
    public void onClick(View v) {
    }

    /************************************Listener*********************************/

    private MediaPlayerListener.ScreenChangedListener screenChangedListener;

    public MediaPlayerListener.ScreenChangedListener getScreenChangedListener() {
        return screenChangedListener;
    }

    public void setScreenChangedListener(MediaPlayerListener.ScreenChangedListener screenChangedListener) {
        this.screenChangedListener = screenChangedListener;
    }
}

播放界面伪代码块

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ideaMediaPlayer.setScreenChangedListener(this);
}

@Override
public void onLandScape() {
        titleView.setVisibility(View.GONE);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}

@Override
public void onPortailScreen() {
        titleView.setVisibility(View.VISIBLE);
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

第一个知识点,如何实现小屏、全屏无缝切换

【Android 音视频开发打怪升级:FFmpeg音视频编解码篇】二、Android 引入FFmpeg 【声 明】 首先,这一系列文章均基于自己的理解和实践,可能有不对的地方,欢迎大家指正。 其次,这是一个入门系列,涉及的知识也仅限于够用,深入的知识网上也有许许多多的博文供大家学习了。 最后,写文章过程中,会借鉴参考其他人分享的文章,会在文章最后列出,感谢这些作者的分享。 码字不易,转载请注明出处! 教程代码:【Github传送门】 目录 一、Android音视频硬解码篇: 1,音视频基础知识 2,音视频硬解码流程:封装基础解码框架 3,音视频播放:音视频同步 4,音视频解封和封装:生成. 阅读详情

相关推荐

Android多媒体开发与应用(二):Android音视频处理

目录 第一章:音频管理 第二章:视频播放 一、使用系统中已安装的播放器app(使用Intent方式播放)。 二、使用VideoView配合MediaController播放。 三、使用SurfaceView配合MediaPlayer播放 第三章 拍照功能实现及应用 一、调用系统相机 二、使用 Camera API 第四章 音频录制与播放 一、音频录制 二、音频播放 三、动态...

zhang_zxk的博客 2769

iOS短视频篇:音视频编辑之音视频合成,添加水印及音视频导出

基本介绍 音视频编辑主要依靠AVFoundation框架,首先要有一个AVMutableComposition对象composition,一个composition可以简单的认为是一组轨道(tracks)的集合,这些轨道可以是来自不同媒体资源AVAsset,AVMutableComposition提供了接口来插入或者删除轨道,也可以调整这些轨道的顺序。 下面这张图反映了一个新的 mixComp...

weixin_42433480的博客 4908

【Android 音视频开发打怪升级:音视频硬解码篇】二、音视频硬解码流程:封装基础解码框架(1)

MediaCodec 是Android 4.1(api 16)版本引入的编解码接口,同时支持音视频的编码和解码。一定要好好理解接下来这两幅图,因为后续的代码就是基于这两幅图来编写的。因此,我们将整个解码流程抽象为一个解码基类:BaseDecoder,为了规范代码和更好的拓展性,我们先定义一个解码器:IDecoder,继承Runnable。/**暂停解码*//**继续解码*/fun goOn()/**停止解码*/fun stop()/**是否正在解码*//**

2401_84132544的博客 1317

【音视频安卓开发 (二)】

用可见的方式来记录和分享每一次收获 105

音视频开发二:Android平台PCM 数据的采集

前言 Android SDK 提供了两套音频采集的API,分别是:MediaRecorder 和 AudioRecord,前者是一个更加上层一点的API,它可以直接把手机麦克风录入的音频数据进行编码压缩(如AMR、MP3等)并存成文件,而后者则更接近底层,能够更加自由灵活地控制,可以得到原始的一帧帧PCM音频数据。本文近记录AudioRecord的定义和使用。 AudioRecord基础概念 AudioRecord官方概念定义 AudioRecord类的主要功能是让各种java应用能够管理音频资源,以便它们

langzicanyue的博客 1296

Jasper Report使用JSON数据源创建报表

最近在做一个项目小功能,表单结案要生成PDF报表。 起初,想用HTML模板(art-template模板引擎)编写,利用浏览器的打印功能保存成pdf文件下载。但是HTML编写好的模板,页码、页眉、页脚设置有坑,表单内容中的表格较多,表格不能设置跨页,导致跨页的表格内容与页眉重叠,没能解决这个问题。 于是,转战研究Jasper report生成报表,用更加专业的报表生成工具来做。刚开始,也是跌跌撞撞,遇到了很多问题,因为觉得没有退路了,必须要用这个搞出来,所以就硬着头皮去找各种资料。 主要使用的json

xiaogege2012的专栏 3319

Android音视频开发(二)——Android编码实践

一、Android Camera API 1.1 图像采集 构建预览布局——使用SurfaceView或者TextureView 打开相机 ——Camera.open 设置参数——Camera.Parameters 设置预览数据回调——PreviewCallback 设置预览画布并启动——setPreviewTexture/startPreview 释放相机——stopPreview/release 二、MediaCodec 实践 2.1 MediaCodec (虽然常

indeedes的博客 1686

Visionpro 使用CogPMAlignTool工具提取匹配轮廓点

【代码】Visionpro 使用CogPMAlignTool工具提取匹配轮廓点。

weixin_43947315的博客 2091

Android音视频开发入门(二)

目标一:在 Android 平台绘制一张图片,使用至少 3 种不同的 API,ImageView,SurfaceView,自定义 View ImageView绘制图片,因为ImageView是Android的控件,所以不管是在xml中还是用java代码都是比较好实现的,用setImageResource、setImageBitmap、setImageDrawable、setBackGround等...

Lewis的专栏 858

3DE重客户端安装

3DE重客户端安装

m0_48170265的博客 9425

centos7 python3.12.1 报错 No module named _ssl,坑我几个小时

网上的教程很多,但几乎是无效的,跟着我这教程,可以完美解决。

Amio_的博客 1万+

Android WebRTC 音视频开发总结(二)

Android WebRTC 音视频开发总结(二) 2014-03-04 13:46 by Blacker, 3087 阅读, 4 评论, 收藏, 编辑 上节介绍了WebRTC代码编译和WebRTCDemo的运行,这节主要介绍WebRTCDemo的结构,以此来简单了解WebRTC的调用流程。 1、先看WebRTCDemo的代码结构,如下图: 2、WebRTCDemo中音视频管理

This My Life - chisj 1751

TMS320F280049C 学习笔记4 Led_ex1_blinky 初始化函数及系统时钟

承接上一篇学习笔记,这次开始实际运行例程。本文概述了280049C的第一个实验 Led灯闪烁。同时也总结了系统的初始化函数和时钟配置。

whyorwhnt的专栏 7029

Android FFMPEG音视频开发(二)

Android FFMPEG

WillScorpio 773

BACnet协议栈基本对象BI、BO、AI、AO、AV以及device和File对象介绍

BACnet协议栈基本对象BI、BO、AI、AO、AV以及device和File对象介绍

shufawangzhang的博客 3986

超导电动悬浮系统一体化地面线圈电-热-力特性研究——基于ANSYS Maxwell与Workbench的多物理场联合仿真

摘要:超导电动悬浮(EDS)系统的地面线圈在运行中面临电-热-力多物理场强耦合挑战。本文基于ANSYS Maxwell和Workbench平台,提出一套联合仿真方法,对地面线圈进行高保真多物理场耦合分析。研究通过建立参数化三维电磁模型,计算瞬态涡流损耗和电磁力分布,并顺序耦合至热分析和结构分析,揭示电-热-力特性的相互影响机制。该方法为地面线圈的优化设计、材料选型和可靠性评估提供了理论依据和仿真工具支撑。 关键词:超导电动悬浮;地面线圈;多物理场耦合;联合仿真;ANSYS

huanghm88的专栏 374

Android音视频开发(二)SurfaceView

简介 官方API文档介绍:SurfaceView是View的子类,它内嵌了一个专门用于绘制的Surface,你可以控制这个Surface的格式和尺寸,Surfaceview控制这个Surface的绘制位置。 surface是纵深排序(Z-ordered)的,这表明它总在自己所在窗口的后面。SurfaceView提供了一个可见区域,只有在这个可见区域内的surface内容才可见。surface的排版...

king的专栏 1049

ESP32-C3入门教程 问题篇⑳——subprocess.CalledProcessError: Command ‘[‘D:\\.espressif\\python_env\\idf5.4_py3.

ESP32-C3入门教程 问题篇⑳——subprocess.CalledProcessError: Command '['D:\\.espressif\\python_env\\idf5.4_py3.

772
上一篇: android开发之音视频(一)
下一篇: Android开发之仿淘宝商品详情页
AnalyzeSystem
博客等级 码龄11年 204粉丝 114原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值