我正在寻找有效的方法来减少一些视频权重(作为File上传),明显的答案是:让我们降低分辨率!(全高清或4K不需要,简单的高清对我来说已经足够了)我已经尝试了很多方法应该通过很多API(需要10),最好的方法是使用android-ffmpeg-java,但是...我的漂亮快速几乎当前的旗舰设备整个过程持续约length_of_video*4秒,此lib的重量是9 Mb,这个数量增加了我的应用程序大小...没有wai!(12 Mb到1 Mb是很好的结果,但仍然有太多的缺陷)
所以我决定使用原生的Android方式来实现这一点,MediaMuxer并且MediaCodec- 它们分别来自API18和API16(旧设备用户:抱歉;但他们也经常使用"低分辨率"相机).下面的方法几乎可以工作 - MediaMuxer不尊重MediaFormat.KEY_WIDTH和MediaFormat.KEY_HEIGHT- 提取File是"重新压缩",重量稍微小一点,但分辨率与原始视频相同File...
那么,问题:如何使用MediaMuxer和其他随附的类和方法压缩和重新调整/更改视频的分辨率?
public File getCompressedFile(String videoPath) throws IOException{
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(videoPath);
int trackCount = extractor.getTrackCount();
String filePath = videoPath.substring(0, videoPath.lastIndexOf(File.separator));
String[] splitByDot = videoPath.split("\\.");
String ext="";
if(splitByDot!=null && splitByDot.length>1)
ext = splitByDot[splitByDot.length-1];
String fileName = videoPath.substring(videoPath.lastIndexOf(File.separator)+1,
videoPath.length());
if(ext.length()>0)
fileName=fileName.replace("."+ext, "_out."+ext);
else
fileName=fileName.concat("_out");
final File outFile = new File(filePath, …Run Code Online (Sandbox Code Playgroud) 我从http://bigflake.com/mediacodec/运行CameraToMpegTest.java时遇到问题.当我从Activity开始时:
public class MyActivity extends Activity {
private CameraToMpegTest ctmt = new CameraToMpegTest();
...
@Override
protected void onResume() {
super.onResume();
try {
ctmt.testEncodeCameraToMp4();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
...
Run Code Online (Sandbox Code Playgroud)
我以这个logcat结束:
D/CameraToMpegTest? video/avc output 640x480 @6000000
D/CameraToMpegTest? Camera preview size is 640x480
I/OMXClient? Using client-side OMX mux.
E/ACodec? [OMX.Nvidia.h264.encoder] storeMetaDataInBuffers (output) failed w/ err -2147483648
I/ACodec? setupVideoEncoder succeeded
D/libEGL? loaded /system/lib/egl/libEGL_tegra.so
D/libEGL? loaded /system/lib/egl/libGLESv1_CM_tegra.so
D/libEGL? loaded /system/lib/egl/libGLESv2_tegra.so
I/CameraToMpegTest? Output file is /storage/emulated/0/test.640x480.mp4
W/System.err? java.lang.IllegalStateException: Can't stop …Run Code Online (Sandbox Code Playgroud) 我需要将视频解码为一系列位图,以便我能够修改它们,然后将它们压缩回android中的视频文件.
我计划通过使用getFrameAtTime并将其保存到图像序列来管理它.然后我可以修改序列中的图像并将其编码回电影.但我有两个问题:
getFrameAtTime它用于创建缩略图,并且不保证返回正确的帧.这使视频滞后.我读到使用MediaExtractor进行解码的正确方法,这很好,但我只有示例直接将它呈现给a surfaceView.有什么方法可以将我转换outputBuffer为位图吗?
我需要它来使用16级及以上的api级别.
我正在尝试使用MediaCodec和MediaMux,我遇到了一些麻烦.
以下是logcat的错误:
12-13 11:59:58.238: E/AndroidRuntime(23218): FATAL EXCEPTION: main
12-13 11:59:58.238: E/AndroidRuntime(23218): java.lang.RuntimeException: Unable to resume activity {com.brendon.cameratompeg/com.brendon.cameratompeg.CameraToMpeg}: java.lang.IllegalStateException: Can't stop due to wrong state.
12-13 11:59:58.238: E/AndroidRuntime(23218): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2918)
Run Code Online (Sandbox Code Playgroud)
代码在"mStManager.awaitNewImage();"处出错,它位于onResume函数中.logcat说"相机帧等待时间".
mStManager是SurfaceTextureManager类的一个实例.并且"相机帧等待时间"来自awaitNewImage()函数.我已将该课程添加到我的帖子中.
我的部分代码是这样的(onCreate函数和onResume函数):
@Override
protected void onCreate(Bundle savedInstanceState) {
// arbitrary but popular values
int encWidth = 640;
int encHeight = 480;
int encBitRate = 6000000; // Mbps
Log.d(TAG, MIME_TYPE + " output " + encWidth + "x" + encHeight + " @" + encBitRate);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera_to_mpeg);
prepareCamera(encWidth, encHeight);
prepareEncoder(encWidth, encHeight, …Run Code Online (Sandbox Code Playgroud)