我正在开发一个应用程序,我必须使用自定义相机捕获视频并将视频保存为.mp4视频
我正在使用这些方法对其进行编码
private String encodeVideoTobase64(Uri uri , int index)
{
String videodata = "";
String[] filePathColumn = { MediaStore.Video.Media.DATA };
Cursor cursor = this.getContentResolver().query(uri,filePathColumn, null, null, null);
String videoPath;
try{
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
videoPath = cursor.getString(columnIndex);
}
catch(Exception e)
{
videoPath = PathsOfVideos.get(index);
}
try {
@SuppressWarnings("resource")
FileInputStream v_input = new FileInputStream(videoPath);
ByteArrayOutputStream objByteArrayOS = new ByteArrayOutputStream();
byte[] byteBufferString = new byte[8192];
for (int readNum; (readNum = v_input.read(byteBufferString)) != -1;)
{
objByteArrayOS.write(byteBufferString, 0, readNum);
System.out.println("read " + readNum + " bytes,");
}
videodata = encodeBytes(byteBufferString);//Base64.encodeToString(objByteArrayOS.toByteArray(), Base64.DEFAULT);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return videodata;
}
public static String encodeBytes( byte[] source ) {
// Since we're not going to have the GZIP encoding turned on,
// we're not going to have an java.io.IOException thrown, so
// we should not force the user to have to catch it.
String encoded = null;
try {
encoded = encodeBytes(source, 0, source.length, NO_OPTIONS);
} catch (java.io.IOException ex) {
assert false : ex.getMessage();
} // end catch
assert encoded != null;
return encoded;
}
public static String encodeBytes( byte[] source, int off, int len, int options ) throws java.io.IOException {
byte[] encoded = encodeBytesToBytes( source, off, len, options );
// Return value according to relevant encoding.
try {
return new String( encoded, "US-ASCII");
} // end try
catch (java.io.UnsupportedEncodingException uue) {
return new String( encoded );
} // end catch
}
编码完成,编码的视频成功传送到我的数据库。 我的问题是当我试图再次获取视频并尝试对其进行解码以将其显示给用户时。该视频无法播放。
这就是我尝试使用decodeFast
库中的MiGBas64
方法解码视频
protected void showInstVideo(int pos) {
// TODO Auto-generated method stub
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_video);
//Decode String To Video With mig Base64.
String encodedString = r.getRecipeInstructions().get(pos).getVideoStr();
if (encodedString.compareTo("")!=0) {
byte[] decodedBytes = MiGBase64.decodeFast(encodedString.getBytes());
try {
Date date=new Date();
String filename="/rec"+ date.toString().replace(" ", "_").replace(":", "_")+".mp4";
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root+"/MyAppName");
if (!myDir.exists())
myDir.mkdir();
File file = new File (myDir, filename);
FileOutputStream out = new FileOutputStream(file);
out.write(decodedBytes);
out.close();
VideoView instvideo = (VideoView) dialog.findViewById(R.id.vvdetails);
MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(instvideo);
Uri video = Uri.parse(file.getPath());
instvideo.setVideoURI(video);
if (video != null )
{
dialog.show();
instvideo.start();
}
} catch (Exception e) {
// TODO: handle exception
Log.e("Error", e.toString());
}
}
}
现在我很困惑。我不知道使用哪种方法有误。编码方法还是解码方法?
请你帮我解决一下代码中的问题。
任何帮助将不胜感激。 提前致谢
编辑:
public static byte[] encodeBytesToBytes( byte[] source, int off, int len, int options ) throws java.io.IOException {
if( source == null ){
throw new NullPointerException( "Cannot serialize a null array." );
} // end if: null
if( off < 0 ){
throw new IllegalArgumentException( "Cannot have negative offset: " + off );
} // end if: off < 0
if( len < 0 ){
throw new IllegalArgumentException( "Cannot have length offset: " + len );
} // end if: len < 0
if( off + len > source.length ){
throw new IllegalArgumentException(
String.format( "Cannot have offset of %d and length of %d with array of length %d", off,len,source.length));
} // end if: off < 0
// Compress?
if( (options & GZIP) != 0 ) {
java.io.ByteArrayOutputStream baos = null;
java.util.zip.GZIPOutputStream gzos = null;
MyBase64.OutputStream b64os = null;
try {
// GZip -> Base64 -> ByteArray
baos = new java.io.ByteArrayOutputStream();
b64os = new MyBase64.OutputStream( baos, ENCODE | options );
gzos = new java.util.zip.GZIPOutputStream( b64os );
gzos.write( source, off, len );
gzos.close();
} // end try
catch( java.io.IOException e ) {
// Catch it and then throw it immediately so that
// the finally{} block is called for cleanup.
throw e;
} // end catch
finally {
try{ gzos.close(); } catch( Exception e ){}
try{ b64os.close(); } catch( Exception e ){}
try{ baos.close(); } catch( Exception e ){}
} // end finally
return baos.toByteArray();
} // end if: compress
// Else, don't compress. Better not to use streams at all then.
else {
boolean breakLines = (options & DO_BREAK_LINES) != 0;
//int len43 = len * 4 / 3;
//byte[] outBuff = new byte[ ( len43 ) // Main 4:3
// + ( (len % 3) > 0 ? 4 : 0 ) // Account for padding
// + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines
// Try to determine more precisely how big the array needs to be.
// If we get it right, we don't have to do an array copy, and
// we save a bunch of memory.
int encLen = ( len / 3 ) * 4 + ( len % 3 > 0 ? 4 : 0 ); // Bytes needed for actual encoding
if( breakLines ){
encLen += encLen / MAX_LINE_LENGTH; // Plus extra newline characters
}
byte[] outBuff = new byte[ encLen ];
int d = 0;
int e = 0;
int len2 = len - 2;
int lineLength = 0;
for( ; d < len2; d+=3, e+=4 ) {
encode3to4( source, d+off, 3, outBuff, e, options );
lineLength += 4;
if( breakLines && lineLength >= MAX_LINE_LENGTH )
{
outBuff[e+4] = NEW_LINE;
e++;
lineLength = 0;
} // end if: end of line
} // en dfor: each piece of array
if( d < len ) {
encode3to4( source, d+off, len - d, outBuff, e, options );
e += 4;
} // end if: some padding needed
// Only resize array if we didn't guess it right.
if( e <= outBuff.length - 1 ){
// If breaking lines and the last byte falls right at
// the line length (76 bytes per line), there will be
// one extra byte, and the array will need to be resized.
// Not too bad of an estimate on array size, I'd say.
byte[] finalOut = new byte[e];
System.arraycopy(outBuff,0, finalOut,0,e);
//System.err.println("Having to resize array from " + outBuff.length + " to " + e );
return finalOut;
} else {
//System.err.println("No need to resize array.");
return outBuff;
}
} // end else: don't compress
} // end encodeBytesToBytes
private static byte[] encode3to4(
byte[] source, int srcOffset, int numSigBytes,
byte[] destination, int destOffset, int options ) {
byte[] ALPHABET = getAlphabet( options );
int inBuff = ( numSigBytes > 0 ? ((source[ srcOffset ] << 24) >>> 8) : 0 )
| ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 )
| ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 );
switch( numSigBytes )
{
case 3:
destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ];
destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ];
destination[ destOffset + 3 ] = ALPHABET[ (inBuff ) & 0x3f ];
return destination;
case 2:
destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ];
destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ];
destination[ destOffset + 3 ] = EQUALS_SIGN;
return destination;
case 1:
destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ];
destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ];
destination[ destOffset + 2 ] = EQUALS_SIGN;
destination[ destOffset + 3 ] = EQUALS_SIGN;
return destination;
default:
return destination;
} // end switch
}
private final static byte[] getAlphabet( int options ) {
if ((options & URL_SAFE) == URL_SAFE) {
return _URL_SAFE_ALPHABET;
} else if ((options & ORDERED) == ORDERED) {
return _ORDERED_ALPHABET;
} else {
return _STANDARD_ALPHABET;
}
}