MediaUtils.uts 4.9 KB
Newer Older
1
import {
DCloud-yyl's avatar
DCloud-yyl 已提交
2
	GetVideoInfoSuccess,
3 4 5
} from "../../interface.uts"
import {
	UniError_GetVideoInfo,
DCloud-yyl's avatar
DCloud-yyl 已提交
6
	MediaErrorImpl
7
} from "../../unierror.uts"
DCloud-yyl's avatar
DCloud-yyl 已提交
8

9 10 11 12 13 14
import File from 'java.io.File';
import MediaMetadataRetriever from 'android.media.MediaMetadataRetriever';
import BigDecimal from 'java.math.BigDecimal';
import MediaExtractor from 'android.media.MediaExtractor';
import MediaFormat from 'android.media.MediaFormat';
import TextUtils from 'android.text.TextUtils';
DCloud-yyl's avatar
DCloud-yyl 已提交
15 16 17 18 19
import FileOutputStream from 'java.io.FileOutputStream';
import FileInputStream from 'java.io.FileInputStream';
import InputStream from 'java.io.InputStream';

const ASSETS_PATH = '/android_asset/'
20 21

export function getVideoMetadata(src : string) : any {
DCloud-yyl's avatar
DCloud-yyl 已提交
22
	let videoInfo : GetVideoInfoSuccess = {
23 24 25 26 27
		duration: 0,
		size: 0,
		height: 0,
		width: 0
	}
DCloud-yyl's avatar
DCloud-yyl 已提交
28 29 30 31 32 33 34 35 36 37
	var path = UTSAndroid.convert2AbsFullPath(src)
	if (path.startsWith("/android_asset/")) {
		var mediaCachePath = UTSAndroid.getAppCachePath() + "uni-media/_" + System.currentTimeMillis()
		if (copyFile(path, mediaCachePath)) {
			path = mediaCachePath
		} else {
			let error = new MediaErrorImpl(1101010, UniError_GetVideoInfo);
			return error
		}
	}
38 39
	let videoFile = new File(path)
	if (!videoFile.exists()) {
DCloud-yyl's avatar
DCloud-yyl 已提交
40
		let error = new MediaErrorImpl(1101003, UniError_GetVideoInfo);
41 42
		return error
	}
DCloud-yyl's avatar
DCloud-yyl 已提交
43
	videoInfo.size = videoFile.length() / 1024;
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
	try {
		let retriever = new MediaMetadataRetriever()
		retriever.setDataSource(path)
		let durationStr : string | null = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
		let width : number | null = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)?.toFloat()
		let height : number | null = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)?.toFloat()
		let rotation : string | null = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION)
		if ("90" == rotation || "270" == rotation) {
			videoInfo.width = height != null ? height! : 0
			videoInfo.height = width != null ? width : 0
		} else {
			videoInfo.width = width != null ? width : 0
			videoInfo.height = height != null ? height : 0
		}
		switch (rotation) {
			case "90":
				rotation = "right";
				break;
			case "270":
				rotation = "left";
				break;
			case "180":
				rotation = "down";
				break;
			default:
				rotation = "up";
				break;
		}
		var duration : number = 0
		if (durationStr != null) {
			try {
				duration = durationStr.toFloat()
			} catch (e) {
			}
		}
		let big : BigDecimal = BigDecimal.valueOf(duration.toDouble() / 1000).setScale(2, BigDecimal.ROUND_HALF_UP)
		videoInfo.duration = big.toFloat()
		videoInfo.orientation = rotation!
		let mimeType : string | null = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE);
		videoInfo.type = mimeType
		let bitrateStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE);
		var bitrate : number | null = null
		try {
			if (bitrateStr != null) {
				bitrate = (bitrateStr.toFloat() / 1000).toInt()
			}
		} catch (e) { }
		videoInfo.bitrate = bitrate
		var fpsNum : number | null = null
		let fps : string | null = retriever.extractMetadata(32);
		if (TextUtils.isEmpty(fps)) {
			let extractor = new MediaExtractor()
			extractor.setDataSource(path)
			let trackCount = extractor.getTrackCount();
			for (var i = 0; i < trackCount; i++) {
				let mediaFormat = extractor.getTrackFormat(i.toInt());
				let mimeType = mediaFormat.getString(MediaFormat.KEY_MIME);
				if (!TextUtils.isEmpty(mimeType) && mimeType!!.startsWith("video/")) {
					let frame = mediaFormat.getInteger(MediaFormat.KEY_FRAME_RATE);
					fpsNum = frame
				}
			}
		} else {
			try { fpsNum = Math.ceil(((fps!!).toFloat() / (duration)) * 1000) } catch (e) { } // 沿用1.0设计,向上取整
		}
		videoInfo.fps = fpsNum
		return videoInfo
	} catch (e) {
DCloud-yyl's avatar
DCloud-yyl 已提交
112
		let error = new MediaErrorImpl(1101010, UniError_GetVideoInfo);
113 114
		return error
	}
DCloud-yyl's avatar
DCloud-yyl 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
}


export function copyFile(fromFilePath : string, toFilePath : string) : boolean {
	var fis : InputStream | null = null
	try {
		if (fromFilePath.startsWith(ASSETS_PATH)) {
			fis = UTSAndroid.getUniActivity()!.getAssets().open(fromFilePath.replace(ASSETS_PATH, ""));
		} else {
			let fromFile = new File(fromFilePath)
			if (!fromFile.exists()) {
				return false;
			}
			if (!fromFile.isFile()) {
				return false
			}
			if (!fromFile.canRead()) {
				return false;
			}
			fis = new FileInputStream(fromFile);
		}
		if (fis == null) {
			return false
		}
	} catch (e) {
		return false;
	}
	let toFile = new File(toFilePath)
	if (!toFile.getParentFile().exists()) {
		toFile.getParentFile().mkdirs()
	}
	if (!toFile.exists()) {
		toFile.createNewFile()
	}
	try {
		let fos = new FileOutputStream(toFile)
		let byteArrays = ByteArray(1024)
		var c = fis!!.read(byteArrays)
		while (c > 0) {
			fos.write(byteArrays, 0, c)
			c = fis!!.read(byteArrays)
		}
		fis!!.close()
		fos.close()
		return true
	} catch (e) {
		return false;
	}
163
}