源代码文件
PlayVideoActivity.java: cts\apps\CtsVerifier\src\com\android\cts\verifier\streamquality\
StreamingVideoActivity.java:cts\apps\CtsVerifier\src\com\android\cts\verifier\streamquality\
最新收到了从Multimedia组转过来的6个CTS Verifiier的bug,看到bug就很奇怪,视频播放的bug怎么转到我们这边来了呢。后来在log中发现了如下的log:
MyHandler: [MyHandler][msg] 'conn', connection request completed with result -110 (Connection timed out)
所以判断是网络连接出现了错误,让我们过去看看。
拿到bug之后,首先去找了CTS Verifier关于Streaming Video Quaility源代码,发现这个case其实是根据网络视频地址,使用MediaPlayer播放到SurfaceView上的。主要看PlayVideoActivity.java中onCretae()和playVideo()函数就可以知道了,源代码如下:
private Stream mStream;
private SurfaceHolder mHolder;
private SurfaceView mSurfaceView;
private FrameLayout mVideoFrame;
private MediaPlayer mPlayer;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
........
mSurfaceView = (SurfaceView) findViewById(R.id.surface);
mVideoFrame = (FrameLayout) findViewById(R.id.videoframe);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mStream = (Stream) getIntent().getSerializableExtra(EXTRA_STREAM);
}
private void playVideo() {
mPlayer = new MediaPlayer();
mPlayer.setDisplay(mHolder);
mPlayer.setScreenOnWhilePlaying(true);
mPlayer.setOnVideoSizeChangedListener(this);
mPlayer.setOnErrorListener(this);
mPlayer.setOnPreparedListener(this);
try {
mPlayer.setDataSource(mStream.uri);
} catch (IOException e) {
Log.e(TAG, "Unable to play video, setDataSource failed", e);
showDialog(FAIL_DIALOG_ID);
return;
}
mPlayer.prepareAsync();
}
其中mStream就是为网络视频地址,在StreamingVideoActivity.java中生成,我们看看是怎么回事。
private static final Stream[] RTSP_STREAMS = {
new Stream("H263 Video, AMR Audio", "rtsp_h263_amr",
"rtsp://v2.cache7.c.youtube.com/video.3gp?"
+ "cid=0x271de9756065677e&fmt=13&user=android-device-test"),
new Stream("MPEG4 SP Video, AAC Audio", "rtsp_mpeg4_aac",
"rtsp://v2.cache7.c.youtube.com/video.3gp?"
+ "cid=0x271de9756065677e&fmt=13&user=android-device-test"),
new Stream("H264 Base Video, AAC Audio", "rtsp_h264_aac",
"rtsp://v2.cache7.c.youtube.com/video.3gp?"
+ "cid=0x271de9756065677e&fmt=13&user=android-device-test"),
};
private static final Stream[] HTTP_STREAMS = {
new Stream("H263 Video, AMR Audio", "http_h263_amr", "http://v20.lscache8.c.youtube.com/"
+ "videoplayback?id=271de9756065677e"
+ "&itag=13&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
+ "&sparams=ip,ipbits,expire,ip,ipbits,expire,id,itag"
+ "&signature=372FA4C532AA49D14EAF049BCDA66460EEE161E9"
+ ".6D8BF096B73B7A68A7032CA8685053CFB498D30A"
+ "&key=test_key1&user=android-device-test"),
new Stream("MPEG4 SP Video, AAC Audio", "http_mpeg4_aac",
"http://v20.lscache8.c.youtube.com/"
+ "videoplayback?id=271de9756065677e"
+ "&itag=17&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
+ "&sparams=ip,ipbits,expire,ip,ipbits,expire,id,itag"
+ "&signature=3DCD3F79E045F95B6AF661765F046FB0440FF016"
+ ".06A42661B3AF6BAF046F012549CC9BA34EBC80A9"
+ "&key=test_key1&user=android-device-test"),
new Stream("H264 Base Video, AAC Audio", "http_h264_aac",
"http://v20.lscache8.c.youtube.com/"
+ "videoplayback?id=271de9756065677e"
+ "&itag=18&ip=0.0.0.0&ipbits=0&expire=999999999999999999"
+ "&sparams=ip,ipbits,expire,ip,ipbits,expire,id,itag"
+ "&signature=1219C2B07AF0638C27916307A6093C0E43CB894E"
+ ".126B6B916BD57157782738AA7C03E59F21DBC168"
+ "&key=test_key1&user=android-device-test"),
};
我们发现HTTP和RTSP两种播放方式都是由youtube提供的,怀疑网络是否能够翻墙,确认网络是可以访问youtube的。那就非常奇怪了,youtube是可以访问,为什么这些case过不了。最后想到和Android M code对比一下,去看看case有什么不同,结果发现视频地址早就更改了,youtube的网址有的废弃了,使用了google自己的地址,Android M code如下:
private static final String ITAG_13_SIGNATURE =
"53A3A3A46DAB71E3C599DE8FA6A1484593DFACE3" +
".9476B91AD5035D88C3895CC2A4703B6DD442E972";
private static final String ITAG_17_SIGNATURE =
"10D6D263112C41DA98822D74821DF47340F1A361" +
".803649A2258E26BF40E76A95E646FBAE4009CEE8";
private static final String ITAG_18_SIGNATURE =
"618FBB112E1B2FBB66DA9F203AE8CC7DF93C7400" +
".20498AA006E999F42BE69D66E3596F2C7CA18114";
private static final String RTSP_LOOKUP_URI_TEMPLATE =
"http://redirector.c.youtube.com/videoplayback?id=271de9756065677e" +
"&source=youtube&protocol=rtsp&sparams=ip,ipbits,expire,id,itag,source" +
"&ip=0.0.0.0&ipbits=0&expire=19000000000&key=ik0&alr=yes" +
"&itag=%d" +
"&signature=%s";
private static final Stream[] HTTP_STREAMS = {
new Stream("H263 Video, AMR Audio", "http_h263_amr",
"http://redirector.c.play.google.com/"
+ "videoplayback?id=271de9756065677e"
+ "&itag=13&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ "&sparams=ip,ipbits,expire,id,itag"
+ "&signature=073A731E2BDF1E05206AC7B9B895C922ABCBA01D"
+ ".1DDA3F999541D2136E6755F16FC44CA972767169"
+ "&source=youtube"
+ "&key=ik0&user=android-device-test"),
new Stream("MPEG4 SP Video, AAC Audio", "http_mpeg4_aac",
"http://redirector.c.play.google.com/"
+ "videoplayback?id=271de9756065677e"
+ "&itag=17&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ "&sparams=ip,ipbits,expire,id,itag"
+ "&signature=6B0F8B8A6A7FD9E4CDF123349C2E061ED2020D74"
+ ".3460FC81D6C8894BA2D241597D2E1D059845F5F0"
+ "&source=youtube"
+ "&key=ik0&user=android-device-test"),
new Stream("H264 Base Video, AAC Audio", "http_h264_aac",
"http://redirector.c.play.google.com/"
+ "videoplayback?id=271de9756065677e"
+ "&itag=18&ip=0.0.0.0&ipbits=0&expire=19000000000"
+ "&sparams=ip,ipbits,expire,id,itag"
+ "&signature=75627CD4CEA73D7868CBDE3CE5C4011955164107"
+ ".1DCFB0EF1372B48DDCFBE69645FE137AC02AF561"
+ "&source=youtube"
+ "&key=ik0&user=android-device-test"),
};
把M的code merge过去后,case pass。