Android录制mp3格式文件

前言

最近做一个即时通信类的项目,由于要保证pc端,iOS端和Android端的通用性,最终统一为MP3格式,一直担心MP3格式会不会很大,但是实测还是可以接受的。下面来看看具体步骤:

工具

MP3格式是用一个开源项目转的,MP3lame,由于该项目用到了jni,所以需要大家配置好ndk环境,环境配置在此就不多说了,大家可以自行百度,最新的应该很好配置。

创建jni

拷贝文件

下载好后(我下载的是3.98.4版本)打开,找到libmp3lame文件,将里面的.h和.c拷贝下来,在自己的工程里创建jni文件夹,在jni文件夹下新建一个文件夹(我的命名为lame-3.98.4_libmp3lame,后面会用到),将刚才拷贝的文件复制进去,然后再把include文件夹里的lame.h也拷贝进去。

创建Android.mk

在jni中创建文件,Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LAME_LIBMP3_DIR := lame-3.98.4_libmp3lame

LOCAL_MODULE  := mp3lame
LOCAL_SRC_FILES := $(LAME_LIBMP3_DIR)/bitstream.c $(LAME_LIBMP3_DIR)/fft.c $(LAME_LIBMP3_DIR)/id3tag.c $(LAME_LIBMP3_DIR)/mpglib_interface.c $(LAME_LIBMP3_DIR)/presets.c $(LAME_LIBMP3_DIR)/quantize.c $(LAME_LIBMP3_DIR)/reservoir.c $(LAME_LIBMP3_DIR)/tables.c $(LAME_LIBMP3_DIR)/util.c $(LAME_LIBMP3_DIR)/VbrTag.c $(LAME_LIBMP3_DIR)/encoder.c $(LAME_LIBMP3_DIR)/gain_analysis.c $(LAME_LIBMP3_DIR)/lame.c $(LAME_LIBMP3_DIR)/newmdct.c $(LAME_LIBMP3_DIR)/psymodel.c $(LAME_LIBMP3_DIR)/quantize_pvt.c $(LAME_LIBMP3_DIR)/set_get.c $(LAME_LIBMP3_DIR)/takehiro.c $(LAME_LIBMP3_DIR)/vbrquantize.c $(LAME_LIBMP3_DIR)/version.c com_maxi_mp3record_MP3Recorder.c

include $(BUILD_SHARED_LIBRARY)

**注意:**LAME_LIBMP3_DIR := lame-3.98.4_libmp3lame 需要将其改为你的项目中的文件名,即上面说的jni下新建的文件夹。

大家应该看到了最后一句的com_maxi_mp3record_MP3Recorder.c
很明显这是我自己创建的.c文件。用来调用mp3lame中的接口的,对应着我java中的com.maxi.mp3record.MP3Recorder.java。咱们先创建java文件。

创建MP3Recorder.java

对应你的包名建一个MP3Recorder.java文件,该文件是java文件对应你的包名建立即可。

package cn.ctvonline.android.modules.project.widget;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Handler;

/**
 * <b>类功能描述:</b><div style="margin-left:40px;margin-top:-10px">
 * MP3实时录制功能,可暂停,注意因踩用Native开发,不能混淆
 */
public class MP3Recorder {
 private String filePath;
 private int sampleRate;
 private boolean isRecording = false;
 private boolean isPause = false;
 private Handler handler;

 /**
  * 开始录音
  */
 public static final int MSG_REC_STARTED = 1;

 /**
  * 结束录音
  */
 public static final int MSG_REC_STOPPED = 2;

 /**
  * 暂停录音
  */
 public static final int MSG_REC_PAUSE = 3;

 /**
  * 继续录音
  */
 public static final int MSG_REC_RESTORE = 4;

 /**
  * 缓冲区挂了,采样率手机不支持
  */
 public static final int MSG_ERROR_GET_MIN_BUFFERSIZE = -1;

 /**
  * 创建文件时扑街了
  */
 public static final int MSG_ERROR_CREATE_FILE = -2;

 /**
  * 初始化录音器时扑街了
  */
 public static final int MSG_ERROR_REC_START = -3;

 /**
  * 录紧音的时候出错
  */
 public static final int MSG_ERROR_AUDIO_RECORD = -4;

 /**
  * 编码时挂了
  */
 public static final int MSG_ERROR_AUDIO_ENCODE = -5;

 /**
  * 写文件时挂了
  */
 public static final int MSG_ERROR_WRITE_FILE = -6;

 /**
  * 没法关闭文件流
  */
 public static final int MSG_ERROR_CLOSE_FILE = -7;

 public MP3Recorder(int sampleRate) {
  this.sampleRate = sampleRate;
 }

 public void setFilePath(String filePath) {
  this.filePath = filePath;
 }

 /**
  * 开片
  */
 public void start() {
  if (isRecording) {
   return;
  }

  new Thread() {
   @Override
   public void run() {
    android.os.Process
      .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
    // 根据定义好的几个配置,来获取合适的缓冲大小
    final int minBufferSize = AudioRecord.getMinBufferSize(
      sampleRate, AudioFormat.CHANNEL_IN_MONO,
      AudioFormat.ENCODING_PCM_16BIT);
    if (minBufferSize < 0) {
     if (handler != null) {
      handler.sendEmptyMessage(MSG_ERROR_GET_MIN_BUFFERSIZE);
     }
     return;
    }
    AudioRecord audioRecord = new AudioRecord(
      MediaRecorder.AudioSource.MIC, sampleRate,
      AudioFormat.CHANNEL_IN_MONO,
      AudioFormat.ENCODING_PCM_16BIT, minBufferSize * 2);
    // 5秒的缓冲
    short[] buffer = new short[sampleRate * (16 / 8) * 1 * 5];
    byte[] mp3buffer = new byte[(int) (7200 + buffer.length * 2 * 1.25)];

    FileOutputStream output = null;
    try {
     File file = createSDFile(filePath);
     output = new FileOutputStream(file);
    } catch (FileNotFoundException e) {
     if (handler != null) {
      handler.sendEmptyMessage(MSG_ERROR_CREATE_FILE);
     }
     return;
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
    MP3Recorder.init(sampleRate, 1, sampleRate, 32);
    isRecording = true; // 录音状态
    isPause = false; // 录音状态
    try {
     try {
      audioRecord.startRecording(); // 开启录音获取音频数据

      if (mListener != null) {
       mListener.wellPrepared();
      }
     } catch (IllegalStateException e) {
      // 不给录音...
      if (handler != null) {
       handler.sendEmptyMessage(MSG_ERROR_REC_START);
      }
      return;
     }

     try {
      // 开始录音
      if (handler != null) {
       handler.sendEmptyMessage(MSG_REC_STARTED);
      }

      int readSize = 0;
      boolean pause = false;
      while (isRecording) {
       /*--暂停--*/
       if (isPause) {
        if (!pause) {
         handler.sendEmptyMessage(MSG_REC_PAUSE);
         pause = true;
        }
        continue;
       }
       if (pause) {
        handler.sendEmptyMessage(MSG_REC_RESTORE);
        pause = false;
       }
       /*--End--*/
       /*--实时录音写数据--*/
       readSize = audioRecord.read(buffer, 0,
         minBufferSize);
       voiceLevel = getVoiceSize(readSize, buffer);
       if (readSize < 0) {
        if (handler != null) {
         handler.sendEmptyMessage(MSG_ERROR_AUDIO_RECORD);
        }
        break;
       } else if (readSize == 0) {
        ;
       } else {
        int encResult = MP3Recorder.encode(buffer,
          buffer, readSize, mp3buffer);
        if (encResult < 0) {
         if (handler != null) {
          handler.sendEmptyMessage(MSG_ERROR_AUDIO_ENCODE);
         }
         break;
        }
        if (encResult != 0) {
         try {
          output.write(mp3buffer, 0, encResult);
         } catch (IOException e) {
          if (handler != null) {
           handler.sendEmptyMessage(MSG_ERROR_WRITE_FILE);
          }
          break;
         }
        }
       }
       /*--End--*/
      }
      /*--录音完--*/
      int flushResult = MP3Recorder.flush(mp3buffer);
      if (flushResult < 0) {
       if (handler != null) {
        handler.sendEmptyMessage(MSG_ERROR_AUDIO_ENCODE);
       }
      }
      if (flushResult != 0) {
       try {
        output.write(mp3buffer, 0, flushResult);
       } catch (IOException e) {
        if (handler != null) {
         handler.sendEmptyMessage(MSG_ERROR_WRITE_FILE);
        }
       }
      }
      try {
       output.close();
      } catch (IOException e) {
       if (handler != null) {
        handler.sendEmptyMessage(MSG_ERROR_CLOSE_FILE);
       }
      }
      /*--End--*/
     } finally {
      audioRecord.stop();
      audioRecord.release();
     }
    } finally {
     MP3Recorder.close();
     isRecording = false;
    }
    if (handler != null) {
     handler.sendEmptyMessage(MSG_REC_STOPPED);
    }
   }
  }.start();
 }

 public void stop() {
  isRecording = false;
 }

 public void pause() {
  isPause = true;
 }

 public void restore() {
  isPause = false;
 }

 public boolean isRecording() {
  return isRecording;
 }

 public boolean isPaus() {
  if (!isRecording) {
   return false;
  }
  return isPause;
 }

 // 获得声音的level
 public int getVoiceSize(int r, short[] buffer) {
  if (isRecording) {
   try {
    long v = 0;
    // 将 buffer 内容取出,进行平方和运算
    for (int i = 0; i < buffer.length; i++) {
     v += buffer[i] * buffer[i];
    }
    // 平方和除以数据总长度,得到音量大小。
    double mean = v / (double) r;
    double volume = 10 * Math.log10(mean);
    return (((int) volume / 10) - 1);
   } catch (Exception e) {
    // TODO Auto-generated catch block

   }
  }

  return 1;
 }
 /**
  * 在SD卡上创建文件
  *
  * @throws IOException
  */
 public static File createSDFile(String fileName) throws IOException {
  File file = new File(fileName);
  if (!isFileExists(file))
   if (file.isDirectory()) {
    file.mkdirs();
   } else {
    file.createNewFile();
   }
  return file;
 }
 private int voiceLevel;

 public int getVoiceLevel() {
  return voiceLevel;
 }

 public interface AudioStageListener {
  void wellPrepared();
 }

 public AudioStageListener mListener;

 public void setOnAudioStageListener(AudioStageListener listener) {
  mListener = listener;
 }

 /**
  * 录音状态管理
  *
  * @see RecMicToMp3#MSG_REC_STARTED
  * @see RecMicToMp3#MSG_REC_STOPPED
  * @see RecMicToMp3#MSG_REC_PAUSE
  * @see RecMicToMp3#MSG_REC_RESTORE
  * @see RecMicToMp3#MSG_ERROR_GET_MIN_BUFFERSIZE
  * @see RecMicToMp3#MSG_ERROR_CREATE_FILE
  * @see RecMicToMp3#MSG_ERROR_REC_START
  * @see RecMicToMp3#MSG_ERROR_AUDIO_RECORD
  * @see RecMicToMp3#MSG_ERROR_AUDIO_ENCODE
  * @see RecMicToMp3#MSG_ERROR_WRITE_FILE
  * @see RecMicToMp3#MSG_ERROR_CLOSE_FILE
  */
 public void setHandle(Handler handler) {
  this.handler = handler;
 }

 /*--以下为Native部分--*/
 static {
  System.loadLibrary("mp3lame");
 }

 /**
  * 初始化录制参数
  */
 public static void init(int inSamplerate, int outChannel,
   int outSamplerate, int outBitrate) {
  init(inSamplerate, outChannel, outSamplerate, outBitrate, 7);
 }

 /**
  * 初始化录制参数 quality:0=很好很慢 9=很差很快
  */
 public native static void init(int inSamplerate, int outChannel,
   int outSamplerate, int outBitrate, int quality);

 /**
  * 音频数据编码(PCM左进,PCM右进,MP3输出)
  */
 public native static int encode(short[] buffer_l, short[] buffer_r,
   int samples, byte[] mp3buf);

 /**
  * 据说录完之后要刷干净缓冲区
  */
 public native static int flush(byte[] mp3buf);

 /**
  * 结束编码
  */
 public native static void close();
}

创建c文件

在创建c文件,创建在jni下,命名就按你的java文件所在的包名命名”.”替换为“_”。例如:com_maxi_mp3record_MP3Recorder.c。当然还得有头文件:com_maxi_mp3record_MP3Recorder.h。

com_maxi_mp3record_MP3Recorder.c

#include "lame-3.98.4_libmp3lame/lame.h"
#include "com_maxi_mp3record_MP3Recorder.h"

static lame_global_flags *glf = NULL;

JNIEXPORT void JNICALL Java_com_maxi_mp3record_MP3Recorder_init(
  JNIEnv *env, jclass cls, jint inSamplerate, jint outChannel,
  jint outSamplerate, jint outBitrate, jint quality) {
 if (glf != NULL) {
  lame_close(glf);
  glf = NULL;
 }
 glf = lame_init();
 lame_set_in_samplerate(glf, inSamplerate);
 lame_set_num_channels(glf, outChannel);
 lame_set_out_samplerate(glf, outSamplerate);
 lame_set_brate(glf, outBitrate);
 lame_set_quality(glf, quality);
 lame_init_params(glf);
}

JNIEXPORT jint JNICALL Java_com_maxi_mp3record_MP3Recorder_encode(
  JNIEnv *env, jclass cls, jshortArray buffer_l, jshortArray buffer_r,
  jint samples, jbyteArray mp3buf) {
 jshort* j_buffer_l = (*env)->GetShortArrayElements(env, buffer_l, NULL);

 jshort* j_buffer_r = (*env)->GetShortArrayElements(env, buffer_r, NULL);

 const jsize mp3buf_size = (*env)->GetArrayLength(env, mp3buf);
 jbyte* j_mp3buf = (*env)->GetByteArrayElements(env, mp3buf, NULL);

 int result = lame_encode_buffer(glf, j_buffer_l, j_buffer_r,
   samples, j_mp3buf, mp3buf_size);

 (*env)->ReleaseShortArrayElements(env, buffer_l, j_buffer_l, 0);
 (*env)->ReleaseShortArrayElements(env, buffer_r, j_buffer_r, 0);
 (*env)->ReleaseByteArrayElements(env, mp3buf, j_mp3buf, 0);

 return result;
}

JNIEXPORT jint JNICALL Java_com_maxi_mp3record_MP3Recorder_flush(
  JNIEnv *env, jclass cls, jbyteArray mp3buf) {
 const jsize mp3buf_size = (*env)->GetArrayLength(env, mp3buf);
 jbyte* j_mp3buf = (*env)->GetByteArrayElements(env, mp3buf, NULL);

 int result = lame_encode_flush(glf, j_mp3buf, mp3buf_size);

 (*env)->ReleaseByteArrayElements(env, mp3buf, j_mp3buf, 0);

 return result;
}

JNIEXPORT void JNICALL Java_com_maxi_mp3record_MP3Recorder_close(
  JNIEnv *env, jclass cls) {
 lame_close(glf);
 glf = NULL;
}

com_maxi_mp3record_MP3Recorder.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_maxi_mp3record_MP3Recorder */

#ifndef _Included_com_maxi_mp3record_MP3Recorder
#define _Included_com_maxi_mp3record_MP3Recorder
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:  com_maxi_mp3record_MP3Recorder
 * Method: init
 * Signature: (IIIII)V
 */
JNIEXPORT void JNICALL Java_com_maxi_mp3record_MP3Recorder_init
 (JNIEnv *, jclass, jint, jint, jint, jint, jint);

/*
 * Class:  com_maxi_mp3record_MP3Recorder
 * Method: encode
 * Signature: ([S[SI[B)I
 */
JNIEXPORT jint JNICALL Java_com_maxi_mp3record_MP3Recorder_encode
 (JNIEnv *, jclass, jshortArray, jshortArray, jint, jbyteArray);

/*
 * Class:  com_maxi_mp3record_MP3Recorder
 * Method: flush
 * Signature: ([B)I
 */
JNIEXPORT jint JNICALL Java_com_maxi_mp3record_MP3Recorder_flush
 (JNIEnv *, jclass, jbyteArray);

/*
 * Class:  com_maxi_mp3record_MP3Recorder
 * Method: close
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_maxi_mp3record_MP3Recorder_close
 (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

这俩文件别只复制不看内容啊,里面可都是连接java和c的接口,所以不能有差错。举个例子吧,#ifndef _Included_com_maxi_mp3record_MP3Recorder,这个就得替换成你对应的包名,里面所有都得替换成你自己的程序对应的包名。

编译ndk

创建Application.mk在你的项目文件的jni下,在里面写入:
APP_ABI := all
如果不加,NDK只会编译“armeabi”,然而安卓有很多不同类型的处理器,所以我们不止需要arm。相信你们搞到现在了肯定ndk都配置好了,然后打开终端,进入到你的项目(找到你的ndk目录下的ndk-bulid,最好把它添加到环境变量里,对于以后编译比较方便,在此默认你没添加环境变量),执行ndk-bulid。稍等片刻你会发现你的项目里多了一个obj文件夹,obj文件夹下会生成”arm64-v8a”、”armeabi”、”armeabi-v7a”、”mips”、”mips64”、”x86”、”x86_64”。打开它,各个文件夹下会有一个libmp3lame.so。ok,没错那就是你要的“滑板鞋”。将它放入你的libs文件下,没有自行创建,各个平台便都可以加载了。

使用方法

MP3Recorder recorder = new MP3Recorder(8000);
recorder.setFilePath(voicePath);//录音保存目录
recorder.start();//开始录音
recorder.stop();//录音结束
recorder.getVoiceLevel()//这是我封装的获取音频振幅接口,大家可以用来录音的时候显示声音大小,数据自行调节。

总结

之前一直用MediaRecorder录音,发现录出来的只能是amr、acc等格式,用lame转MP3感觉是不可行的。我试了没能成功,不知道具体是什么原因,所以大家有时间可以研究研究,没时间就不要尝试了。

Mp3lame录制出来的声音还是挺靠谱的(不过据听说iOS就有些莎莎声),然后录制出来的大小还是可以接受的,五秒钟的音频大概在20k左右的样子吧。使用还是很方便的。如果有什么疑问或建议请留言哈。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 比较完整的android MP3 LRC歌词滚动高亮显示(附源码)

    1.以前的滚动只是安行来刷新,现在不是按行来滚动了,其实就是在一定时间内整体往上移动,比如说在1S内刷新10次,由于认得肉眼看起来像是滚动. 关键代码如下: 复制代码 代码如下: float plus = currentDunringTime == 0 ? 30                : 30                        + (((float) currentTime - (float) sentenctTime) / (float) currentDunringTim

  • 利用libmp3lame实现在Android上录音MP3文件示例

    之前项目需要实现MP3的录音,于是使用上了Lame这个库.这次做一个demo,使用AndroidStudio+Cmake+NDK进行开发.利用Android SDK提供的AndroidRecorder进行录音,得到PCM数据,并使用jni调用Lame这个C库将PCM数据转换为MP3文件.并使用MediaPlayer对录音的MP3文件进行播放.另外此次的按键是仿微信的语音按键,按下录音,松开结束,若中途上滑松开即取消 效果如下: 项目地址: LameMp3ForAndroid_jb51.rar 一

  • Android编程实现播放MP3功能示例

    本文实例讲述了Android编程实现播放MP3功能.分享给大家供大家参考,具体如下: 在android中播放mp3非常简单,也是项目中经常使用的,比如说要做项目的背景音乐,应用中某些功能的提示音等的.应用非常广泛,下面提供一个简单的使用实例: layout文件的配置: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.and

  • 详解Android应用开发--MP3音乐播放器代码实现(一)

    需求1:将内存卡中的MP3音乐读取出来并显示到列表当中 1.从数据库中查询所有音乐数据,保存到List集合当中,List当中存放的是Mp3Info对象 2.迭代List集合,把每一个Mp3Info对象的所有属性,保存到Map对象当中 3.定义一个List集合,把Map对象添加到List集合当中 4.通过定义一个SimpleAdpter,调用setAdpter方法,将数据显示到列表当中 /** * 用于从数据库中查询歌曲的信息,保存在List当中 * * @return */ public Lis

  • Android实现使用流媒体播放远程mp3文件的方法

    本文实例讲述了Android实现使用流媒体播放远程mp3文件的方法.分享给大家供大家参考,具体如下: package com.shadow.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.

  • Android递归方式删除某文件夹下的所有文件(.mp3文件等等)

    1.由于需要删除文件,因此需要如下权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> 2.核心代码 复制代码 代码如下: package com.example.deleteyoumi; import java.io.File; import android.os.Bundle; import android.os.Han

  • Android录制mp3格式文件

    前言 最近做一个即时通信类的项目,由于要保证pc端,iOS端和Android端的通用性,最终统一为MP3格式,一直担心MP3格式会不会很大,但是实测还是可以接受的.下面来看看具体步骤: 工具 MP3格式是用一个开源项目转的,MP3lame,由于该项目用到了jni,所以需要大家配置好ndk环境,环境配置在此就不多说了,大家可以自行百度,最新的应该很好配置. 创建jni 拷贝文件 下载好后(我下载的是3.98.4版本)打开,找到libmp3lame文件,将里面的.h和.c拷贝下来,在自己的工程里创建

  • Android录音mp3格式实例详解

    Android录音支持的格式有amr.aac,但这两种音频格式在跨平台上表现并不好. MP3显然才是跨平台的最佳选择. 项目地址 GavinCT/AndroidMP3Recorder 实现思路概述 在分析代码前,我们需要明确几个问题 1. 如何最终生成MP3 实现MP3格式最好是借助Lame这个成熟的解决方案. 对于Android来说,需要借助JNI来调用Lame的C语言代码,实现音频格式的转化. 2. 如何获取最初的音频数据 AudioRecord类可以直接帮助我们获取音频数据. 3. 如何进

  • Android音频开发之录制音频(WAV及MP3格式)

    目录 一.音频录制权限: 二.录音文件的配置: 三.音频录制: 1.录音对象初始化: 2.录制wav音频文件: 3.录制MP3音频文件 四.音频录制管理[AudioRecordManager]: 附GitHub源码:MultimediaExplore 首先看下音频录制跟播放效果简图: 上面是录音:长按即可录音,支持声波动画,右滑删除等.支持录制pcm.wav.mp3格式音频. 下面是播放:点击左边扬声器icon,开始播放刚录制的本地音频文件[也支持在线音频播放],支持播放进度,支持切换播放模式(

  • Android录制语音文件wav转mp3的方法示例

    1.Android 使用AudioRecord而实现录音暂停以及wav文件转mp3文件.因为android系统开源的原因,导致许多生产厂商乱改系统源码,此处小米最为恶心,使用android原生的AudioRecord录制只能保存wav和pcm格式的语音文件,但是小米手机录制的wav语音文件系统本身不支持,所以使用MediaPlayer不能播放wav格式的文件,其它手机可以.此时有一万匹草泥马从旁边疾驰而过... 2.针对这个问题解决方案目前有两种: 方案1: 将录制完的wav文件转化成mp3格式

  • Android录制声音文件(音频)并播放

    本文实例为大家分享了Android录制音频文件的具体代码,供大家参考,具体内容如下 1.这个demo中没有对多次点击同一个声音文件做详细处理,偶尔会有崩溃,用的时候需要注意. 2.按住录音按钮录音过程中,只对竖直方向处理了一下,水平方向没写: 3.没有做删除某个声音文件的操作,但是测试的时候实现了功能,需要用到的话,在MainActivity->onItemClick中的TODO中有详细说明: 4.这只是个demo,如果要在项目中使用,先写出demo,没问题了,再引入项目,在写成demo后,在真

  • PHP将amr音频文件转换为mp3格式的操作细节

    说下整体思路 1.服务器安装ffmpeg 2.使用ffmpeg -i 指令来转换amr为mp3格式(这个到时候写在PHP代码中,使用exec函数执行即可) 3.在网页端使用HTML5的audio标签来播放mp3文件 下面是操作细节: 一.服务器安装ffmpeg以centos为例 此处参考:http://my.oschina.NET/ethan09/blog/372435 需要特别注意的是,在下面的方法中,amrnb和amrwb的安装到make环节会请求3gp的一个网址,一般是请求不到的,可以用c

  • Android编程使用pull方式解析xml格式文件的方法详解

    本文实例讲述了Android编程使用pull方式解析xml格式文件的方法.分享给大家供大家参考,具体如下: 上次已经说过使用Android sax解析xml,实际上还可以使用pull解析xml.这样的方式效率也是比较高的.pull不仅可以在Android上使用也可以用在javaee里面,需要的就是pull的jar包.这次的xml也使用上次的那个,如下所示 <?xml version="1.0" encoding="UTF-8"?> <persons

  • Android实现打开各种文件的intent方法小结

    本文实例讲述了Android实现打开各种文件的intent方法.分享给大家供大家参考,具体如下: import android.app.Activity; import Android.content.Intent; import android.net.Uri; import android.net.Uri.Builder; import Java.io.File; import android.content.Intent; //自定义android Intent类, //可用于获取打开以下

  • Android 录制手机屏幕视频生成GIF图片实例详解

    Android 录制手机屏幕视频生成GIF图片实例详解 无图无真相,在我们日常的网络交流中往往需要给交流对象提供直观的显示,而视频是一个很好的方式,但是视频需要播放器,还需要当做文件进行对点传输,并不是很方便.想CSDN这样的博客网站也并不支持在博客里放视频这种方式,除非你贴外链,太烦了不是么.最好是如下图这种gif方式,直观 今天来教大家一个易操作的录制方式.当然,一般只适合Android开发者.因为你需要有AndroidStudio 工具 AndroidStudio(完成手机屏幕的视频录制,

  • Android实现app分享文件到微信功能

    本文实例为大家分享了Android实现app分享文件到微信的具体代码,供大家参考,具体内容如下 两种实现方案: 1.使用WXFileObject构造分享方法发送到微信: 2.调用系统分享方法,把文件直接发送到微信: 那么下面来分别看看怎么实现: 0.准备工作 首先,需要在AndroidManifest.xml中配置FileProvider信息,以适配10以后版本文件读取问题 AndroidManifest.xml <provider android:name="androidx.core.

随机推荐