目前遇到一些问题,记录在此,下一阶段按此思路进行研究
个人理解spydroid中生成sdp的 方法是录制一段虚拟视频吗,然后调用MP4Config 类生成config对象,包含了sps pps等内容。
但是我单独提取的时候提示找不到StsdBoX
然后在网上找到一个直接对MP4文件提取sps pps 信息的java类,经测试可用,但是由于对流媒体方面知识匮乏,也没能完成需求。
下文为获取sps pps的java代码:
package com.devillee;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class ObtainSPSAndPPS {
public void getSPSAndPPS(String fileName) throws IOException {
File file = new File(fileName);
FileInputStream fis = new FileInputStream(file);
int fileLength = (int) file.length();
byte[] fileData = new byte[fileLength];
fis.read(fileData);
// 'a'=0x61, 'v'=0x76, 'c'=0x63, 'C'=0x43
byte[] avcC = new byte[] { 0x61, 0x76, 0x63, 0x43 };
// avcC的起始位置
int avcRecord = 0;
for (int ix = 0; ix < fileLength; ++ix) {
if (fileData[ix] == avcC[0] && fileData[ix + 1] == avcC[1]
&& fileData[ix + 2] == avcC[2]
&& fileData[ix + 3] == avcC[3]) {
// 找到avcC,则记录avcRecord起始位置,然后退出循环。
avcRecord = ix + 4;
break;
}
}
if (0 == avcRecord) {
System.out.println("没有找到avcC,请检查文件格式是否正确");
return;
}
// 加7的目的是为了跳过
// (1)8字节的 configurationVersion
// (2)8字节的 AVCProfileIndication
// (3)8字节的 profile_compatibility
// (4)8 字节的 AVCLevelIndication
// (5)6 bit 的 reserved
// (6)2 bit 的 lengthSizeMinusOne
// (7)3 bit 的 reserved
// (8)5 bit 的numOfSequenceParameterSets
// 共6个字节,然后到达sequenceParameterSetLength的位置
int spsStartPos = avcRecord + 6;
byte[] spsbt = new byte[] { fileData[spsStartPos],
fileData[spsStartPos + 1] };
int spsLength = bytes2Int(spsbt);
byte[] SPS = new byte[spsLength];
// 跳过2个字节的 sequenceParameterSetLength
spsStartPos += 2;
System.arraycopy(fileData, spsStartPos, SPS, 0, spsLength);
printResult("SPS", SPS, spsLength);
// 底下部分为获取PPS
// spsStartPos + spsLength 可以跳到pps位置
// 再加1的目的是跳过1字节的 numOfPictureParameterSets
int ppsStartPos = spsStartPos + spsLength + 1;
byte[] ppsbt = new byte[] { fileData[ppsStartPos],
fileData[ppsStartPos + 1] };
int ppsLength = bytes2Int(ppsbt);
byte[] PPS = new byte[ppsLength];
ppsStartPos += 2;
System.arraycopy(fileData, ppsStartPos, PPS, 0, ppsLength);
printResult("PPS", PPS, ppsLength);
}
private int bytes2Int(byte[] bt) {
int ret = bt[0];
ret <<= 8;
ret |= bt[1];
return ret;
}
private void printResult(String type, byte[] bt, int len) {
System.out.println(type + "长度为:" + len);
String cont = type + "的内容为:";
System.out.print(cont);
for (int ix = 0; ix < len; ++ix) {
System.out.printf("%02x ", bt[ix]);
}
System.out.println("\n----------");
}
public static void main(String[] args) throws IOException {
new ObtainSPSAndPPS().getSPSAndPPS("c:\\myvideo1.mp4");
}
}
测试输出的信息为:
SPS长度为:22
SPS的内容为:67 42 c0 16 ab 40 50 14 d0 80 00 00 03 00 80 00 00 0f 47 8b 17 50
----------
PPS长度为:4
PPS的内容为:68 ce 3c 80
对比spydroid的sdp文件:
v=0
o=- 0 0 IN IP4 192.168.1.106
s=Stream-0
i=N/A
c=IN IP4 192.168.1.100
t=0 0
a=recvonly
m=video 5006 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=42c016;sprop-parameter-sets=Z0LAFqtAUB7QgAAAAwCAAAAPR4sXUA==,aM48gA==;
a=control:trackID=1
其中关键的部分为profile-level-id=42c016;sprop-parameter-sets=Z0LAFqtAUB7QgAAAAwCAAAAPR4sXUA==,aM48gA==;
可以看到sps中的67 后面的值即为 42c016 但是sprop-parameter-sets 我就一直找不到是哪个部分了,对流媒体这方面的知识实在匮乏。
现在打算2个方面着手
1、深入理解一下 spydroid中生成sdp文件的方式,看能不能提取出来 用到自己的项目中去
2、研究流媒体相关知识 sps pps sdp
有大神有相关方面的经验吗,可以指点交流一下~共同进步
2108

被折叠的 条评论
为什么被折叠?



