PageRenderTime 199ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/app/src/main/java/com/newenergy/ui/base/video/LiveControl.java

https://bitbucket.org/hikong/newenergy
Java | 1040 lines | 650 code | 107 blank | 283 comment | 192 complexity | 7ad1cdf4ec2153e030e42b36fcb41a07 MD5 | raw file
  1. package com.newenergy.ui.base.video;
  2. import android.os.SystemClock;
  3. import android.util.Log;
  4. import android.view.SurfaceHolder;
  5. import android.view.SurfaceView;
  6. import com.hik.mcrsdk.rtsp.RtspClient;
  7. import com.hik.mcrsdk.rtsp.RtspClientCallback;
  8. import org.MediaPlayer.PlayM4.Player;
  9. import org.MediaPlayer.PlayM4.Player.MPSystemTime;
  10. import org.MediaPlayer.PlayM4.PlayerCallBack.PlayerDisplayCB;
  11. import java.io.File;
  12. import java.io.FileOutputStream;
  13. import java.io.IOException;
  14. import java.nio.ByteBuffer;
  15. import java.util.Calendar;
  16. /**
  17. * 预览控制层
  18. *
  19. * @author huangweifeng
  20. * @Data 2013-10-21
  21. */
  22. public class LiveControl implements RtspClientCallback, PlayerDisplayCB {
  23. private final String TAG = this.getClass().getSimpleName();
  24. /**
  25. * 创建播放库句柄对象
  26. */
  27. private Player mPlayerHandler;
  28. /**
  29. * 创建RTSP取流库句柄对象
  30. */
  31. private RtspClient mRtspHandler;
  32. /**
  33. * 播放库播放端口
  34. */
  35. private int mPlayerPort = -1;
  36. /**
  37. * 初始化阶段
  38. */
  39. public final int LIVE_INIT = 0;
  40. /**
  41. * 取流阶段
  42. */
  43. public final int LIVE_STREAM = 1;
  44. /**
  45. * 播放阶段
  46. */
  47. public final int LIVE_PLAY = 2;
  48. /**
  49. * 释放资源阶段
  50. */
  51. public final int LIVE_RELEASE = 3;
  52. /**
  53. * 预览状态
  54. */
  55. private int mLiveState = LIVE_INIT;
  56. /**
  57. * 播放地址的URL,支持MAG或者流媒体
  58. */
  59. private String mUrl = "";
  60. /**
  61. * 播放使用的SurfaceView对象
  62. */
  63. private SurfaceView mSurfaceView;
  64. /**
  65. * 创建RTSP引擎索引
  66. */
  67. private int mRtspEngineIndex = RtspClient.RTSPCLIENT_INVALIDATE_ENGINEID;
  68. private LiveCallBack mLiveCallBack = null;
  69. private int connectNum = 0;
  70. /**
  71. * 抓拍图片文件
  72. */
  73. private File mPictureFile = null;
  74. /**
  75. * 录像文件
  76. */
  77. private File mRecordFile = null;
  78. /**
  79. * 是否正在录像
  80. */
  81. private boolean mIsRecord = true;
  82. /**
  83. * 数据流
  84. */
  85. private ByteBuffer mStreamHeadDataBuffer;
  86. /**
  87. * 文件输出流
  88. */
  89. private FileOutputStream mRecordFileOutputStream;
  90. /**
  91. * 播放流量
  92. */
  93. private long mStreamRate = 0;
  94. /**
  95. * 设置SD卡使用限度,当小于256M时,提示SD卡内存不足,根据具体情况可以修改
  96. */
  97. private int mSDCardSize = 256 * 1024 * 1024;
  98. /**
  99. * 转封装状态
  100. */
  101. private int mTransState = -1;
  102. private String mDeviceUserName = "";
  103. private String mDevicePassword = "";
  104. /**
  105. * 构造函数
  106. *
  107. * @param context
  108. */
  109. public LiveControl() {
  110. init();
  111. }
  112. /**
  113. * 控制层初始化方法 void
  114. *
  115. * @since V1.0
  116. */
  117. public void init() {
  118. mPlayerHandler = Player.getInstance();
  119. mRtspHandler = RtspClient.getInstance();
  120. mLiveState = LIVE_INIT;
  121. }
  122. /**
  123. * 设置预览参数
  124. *
  125. * @param url 播放地址(过MAG/流媒体)
  126. * @param name 登录设备的用户名
  127. * @param password 登录设备的密码 void
  128. * @since V1.0
  129. */
  130. public void setLiveParams(String url, String name, String password) {
  131. mUrl = url;
  132. mDeviceUserName = name;
  133. mDevicePassword = password;
  134. }
  135. public void setLiveParams(String url) {
  136. mUrl = url;
  137. }
  138. /**
  139. * 设置控制层回调接口
  140. *
  141. * @param liveCallBack
  142. * @since V1.0
  143. */
  144. public void setLiveCallBack(LiveCallBack liveCallBack) {
  145. mLiveCallBack = liveCallBack;
  146. }
  147. /**
  148. * 启动控制层播放
  149. *
  150. * @param surfaceView
  151. * @since V1.0
  152. */
  153. public void startLive(SurfaceView surfaceView) {
  154. if (null == surfaceView) {
  155. Log.e(TAG, "startLive():: surfaceView is null");
  156. return;
  157. }
  158. mSurfaceView = surfaceView;
  159. if (LIVE_STREAM == mLiveState) {
  160. Log.e(TAG, "startLive():: is palying");
  161. }
  162. startRtsp();
  163. }
  164. /**
  165. * 获取当前播放状态
  166. *
  167. * @return LIVE_INIT初始化、LIVE_STREAM取流、LIVE_PLAY播放、LIVE_RELEASE释放资源
  168. * @since V1.0
  169. */
  170. public int getLiveState() {
  171. return mLiveState;
  172. }
  173. /**
  174. * 启动RTSP开始取流
  175. *
  176. * @since V1.0
  177. */
  178. private void startRtsp() {
  179. if (null == mRtspHandler) {
  180. Log.e(TAG, "startRtsp():: mRtspHandler is null");
  181. return;
  182. }
  183. mRtspEngineIndex = mRtspHandler.createRtspClientEngine(this, RtspClient.RTPRTSP_TRANSMODE);
  184. if (mRtspEngineIndex < 0) {
  185. int errorCode = mRtspHandler.getLastError();
  186. Log.e("AAA", "startRtsp():: errorCode is R" + errorCode);
  187. if (null != mLiveCallBack) {
  188. mLiveCallBack.onMessageCallback(ConstantLive.RTSP_FAIL);
  189. }
  190. return;
  191. }
  192. Log.d(TAG,"mRtspEngineIndex: "+ mRtspEngineIndex + "mUrl: " + mUrl +"mDeviceUserName: " + mDeviceUserName +
  193. "mDevicePassword: " + mDevicePassword);
  194. //boolean ret = mRtspHandler.startRtspProc(mRtspEngineIndex, mUrl, mDeviceUserName, mDevicePassword);
  195. boolean ret = mRtspHandler.startRtspProc(mRtspEngineIndex, mUrl/*, mDeviceUserName, mDevicePassword*/);
  196. if (!ret) {
  197. int errorCode = mRtspHandler.getLastError();
  198. Log.e(TAG, "startRtsp():: errorCode is R" + errorCode);
  199. mRtspHandler.releaseRtspClientEngineer(mRtspEngineIndex);
  200. if (null != mLiveCallBack) {
  201. mLiveCallBack.onMessageCallback(ConstantLive.RTSP_FAIL);
  202. }
  203. return;
  204. }
  205. mLiveState = LIVE_STREAM;
  206. if (null != mLiveCallBack) {
  207. mLiveCallBack.onMessageCallback(ConstantLive.RTSP_SUCCESS);
  208. }
  209. }
  210. /**
  211. * 停止预览方法
  212. *
  213. * @since V1.0
  214. */
  215. public void stop() {
  216. if (LIVE_INIT == mLiveState) {
  217. return;
  218. }
  219. if (mIsRecord) {
  220. stopRecord();
  221. mIsRecord = false;
  222. }
  223. stopRtsp();
  224. closePlayer();
  225. if (null != mLiveCallBack) {
  226. mLiveCallBack.onMessageCallback(ConstantLive.STOP_SUCCESS);
  227. }
  228. mLiveState = LIVE_INIT;
  229. }
  230. /**
  231. * 停止RTSP
  232. *
  233. * @since V1.0
  234. */
  235. private void stopRtsp() {
  236. if (null != mRtspHandler) {
  237. if (RtspClient.RTSPCLIENT_INVALIDATE_ENGINEID != mRtspEngineIndex) {
  238. mRtspHandler.stopRtspProc(mRtspEngineIndex);
  239. mRtspHandler.releaseRtspClientEngineer(mRtspEngineIndex);
  240. mRtspEngineIndex = RtspClient.RTSPCLIENT_INVALIDATE_ENGINEID;
  241. }
  242. }
  243. }
  244. /**
  245. * 关闭播放库 void
  246. *
  247. * @since V1.0
  248. */
  249. private void closePlayer() {
  250. if (null != mPlayerHandler) {
  251. if (-1 != mPlayerPort) {
  252. boolean ret = mPlayerHandler.stop(mPlayerPort);
  253. if (!ret) {
  254. Log.e(
  255. TAG,
  256. "closePlayer(): Player stop failed! errorCode is P"
  257. + mPlayerHandler.getLastError(mPlayerPort));
  258. }
  259. ret = mPlayerHandler.closeStream(mPlayerPort);
  260. if (!ret) {
  261. Log.e(TAG, "closePlayer(): Player closeStream failed!");
  262. }
  263. ret = mPlayerHandler.freePort(mPlayerPort);
  264. if (!ret) {
  265. Log.e(TAG, "closePlayer(): Player freePort failed!");
  266. }
  267. mPlayerPort = -1;
  268. }
  269. }
  270. }
  271. /*
  272. * handle - - 引擎id dataType - - 数据类型,决定data数据的类型,包括DATATYPE_HEADER和DATATYPE_STREAM两种类型 data -
  273. * -回调数据,分为:header数据和stream数据,由datatype作区分,header用于初始化播放库 length - - data 数据的长度 timeStamp - - 时间戳(保留) packetNo -
  274. * -rtp包号(保留) useId - - 用户数据,默认就是引擎id与handle相同
  275. */
  276. @Override
  277. public void onDataCallBack(int handle, int dataType, byte[] data, int length, int timeStamp, int packetNo, int useId) {
  278. if (mStreamRate + length >= Long.MAX_VALUE) {
  279. mStreamRate = 0;
  280. }
  281. mStreamRate += length;
  282. switch (dataType) {
  283. case RtspClient.DATATYPE_HEADER:
  284. boolean ret = processStreamHeader(data, length);
  285. if (!ret) {
  286. if (null != mLiveCallBack) {
  287. mLiveCallBack.onMessageCallback(ConstantLive.START_OPEN_FAILED);
  288. return;
  289. } else {
  290. Log.e(TAG, "onDataCallBack():: mLiveCallBack is null");
  291. }
  292. } else {
  293. Log.e(TAG, "MediaPlayer Header success!");
  294. }
  295. break;
  296. default:
  297. processStreamData(data, length);
  298. break;
  299. }
  300. processRecordData(dataType, data, length);
  301. }
  302. /**
  303. * 录像数据处理
  304. *
  305. * @param dataType 数据流
  306. * @param dataBuffer 数据缓存
  307. * @param dataLength 数据长度
  308. */
  309. private void processRecordData(int dataType, byte[] dataBuffer, int dataLength) {
  310. if (null == dataBuffer || dataLength == 0) {
  311. return;
  312. }
  313. if (mIsRecord) {
  314. if (RtspClient.DATATYPE_HEADER == dataType) {
  315. mStreamHeadDataBuffer = ByteBuffer.allocate(dataLength);
  316. for (int i = 0; i < dataLength; i++) {
  317. mStreamHeadDataBuffer.put(dataBuffer[i]);
  318. }
  319. } else if (RtspClient.DATATYPE_STREAM == dataType) {
  320. writeStreamData(dataBuffer, dataLength);
  321. }
  322. } else {
  323. if (-1 != mTransState) {
  324. mTransState = -1;
  325. }
  326. }
  327. }
  328. /**
  329. * 录像数据写到文件
  330. *
  331. * @param recordData 录像数据
  332. * @param length 录像数据长度
  333. * @since V1.0
  334. */
  335. private boolean writeStreamData(byte[] recordData, int length) {
  336. if (null == recordData || length <= 0) {
  337. return false;
  338. }
  339. if (null == mRecordFile) {
  340. return false;
  341. }
  342. try {
  343. if (null == mRecordFileOutputStream) {
  344. mRecordFileOutputStream = new FileOutputStream(mRecordFile);
  345. }
  346. mRecordFileOutputStream.write(recordData, 0, length);
  347. Log.e(TAG, "writeStreamData() success");
  348. } catch (Exception e) {
  349. e.printStackTrace();
  350. return false;
  351. }
  352. return true;
  353. }
  354. /**
  355. * 处理数据流头
  356. *
  357. * @param data
  358. * @param len
  359. * @return boolean
  360. * @since V1.0
  361. */
  362. private boolean processStreamHeader(byte[] data, int len) {
  363. if (-1 != mPlayerPort) {
  364. closePlayer();
  365. }
  366. boolean ret = startPlayer(data, len);
  367. return ret;
  368. }
  369. /**
  370. * 开启播放库方法
  371. *
  372. * @param data
  373. * @param len
  374. * @return boolean
  375. * @since V1.0
  376. */
  377. private boolean startPlayer(byte[] data, int len) {
  378. if (null == data || 0 == len) {
  379. Log.e(TAG, "startPlayer() Stream data error data is null or len is 0");
  380. return false;
  381. }
  382. if (null == mPlayerHandler) {
  383. Log.e(TAG, "startPlayer(): mPlayerHandler is null!");
  384. return false;
  385. }
  386. mPlayerPort = mPlayerHandler.getPort();
  387. if (-1 == mPlayerPort) {
  388. Log.e(TAG, "startPlayer(): mPlayerPort is -1");
  389. return false;
  390. }
  391. boolean ret = mPlayerHandler.setStreamOpenMode(mPlayerPort, Player.STREAM_REALTIME);
  392. if (!ret) {
  393. int tempErrorCode = mPlayerHandler.getLastError(mPlayerPort);
  394. mPlayerHandler.freePort(mPlayerPort);
  395. mPlayerPort = -1;
  396. Log.e(TAG, "startPlayer(): Player setStreamOpenMode failed! errorCord is P" + tempErrorCode);
  397. return false;
  398. }
  399. ret = mPlayerHandler.openStream(mPlayerPort, data, len, 2 * 1024 * 1024);
  400. if (!ret) {
  401. Log.e(TAG, "startPlayer() mPlayerHandle.openStream failed!" + "Port: " + mPlayerPort
  402. + "ErrorCode is P " + mPlayerHandler.getLastError(mPlayerPort));
  403. return false;
  404. }
  405. ret = mPlayerHandler.setDisplayCB(mPlayerPort, this);
  406. if (!ret) {
  407. Log.e(
  408. TAG,
  409. "startPlayer() mPlayerHandle.setDisplayCB() failed errorCode is P"
  410. + mPlayerHandler.getLastError(mPlayerPort));
  411. return false;
  412. }
  413. if (null == mSurfaceView) {
  414. Log.e(TAG, "startPlayer():: mSurfaceView is null");
  415. return false;
  416. }
  417. SurfaceHolder surfaceHolder = mSurfaceView.getHolder();
  418. if (null == surfaceHolder) {
  419. Log.e(TAG, "startPlayer() mPlayer mainSurface is null!");
  420. return false;
  421. }
  422. ret = mPlayerHandler.play(mPlayerPort, surfaceHolder);
  423. if (!ret) {
  424. Log.e(TAG,
  425. "startPlayer() mPlayerHandle.play failed!" + "Port: " + mPlayerPort + "PlayView Surface: "
  426. + surfaceHolder + "errorCode is P" + mPlayerHandler.getLastError(mPlayerPort));
  427. return false;
  428. }
  429. return true;
  430. }
  431. /**
  432. * 抓拍 void
  433. *
  434. * @param filePath 存放文件路径
  435. * @param picName 抓拍时文件的名称
  436. * @return true-抓拍成功,false-抓拍失败
  437. * @since V1.0
  438. */
  439. public boolean capture(String filePath, String picName) {
  440. if (!UtilSDCard.isSDCardUsable()) {
  441. if (null != mLiveCallBack) {
  442. mLiveCallBack.onMessageCallback(ConstantLive.SD_CARD_UN_USEABLE);
  443. }
  444. return false;
  445. }
  446. if (UtilSDCard.getSDCardRemainSize() <= mSDCardSize) {
  447. if (null != mLiveCallBack) {
  448. mLiveCallBack.onMessageCallback(ConstantLive.SD_CARD_SIZE_NOT_ENOUGH);
  449. }
  450. return false;
  451. }
  452. if (LIVE_PLAY != mLiveState) {
  453. mLiveCallBack.onMessageCallback(ConstantLive.CAPTURE_FAILED_NPLAY_STATE);
  454. return false;
  455. }
  456. byte[] pictureBuffer = getPictureOnJPEG();
  457. if (null == pictureBuffer || pictureBuffer.length == 0) {
  458. Log.e(TAG, "capture():: pictureBuffer is null or length 0");
  459. return false;
  460. }
  461. boolean ret = createPictureFile(filePath, picName);
  462. if (!ret) {
  463. pictureBuffer = null;
  464. Log.e(TAG, "capture():: createPictureFile() return false");
  465. return false;
  466. }
  467. ret = writePictureToFile(pictureBuffer, pictureBuffer.length);
  468. if (!ret) {
  469. pictureBuffer = null;
  470. removePictureFile();
  471. Log.e(TAG, "capture():: writePictureToFile() return false");
  472. return false;
  473. }
  474. return true;
  475. }
  476. /**
  477. * 获取JPEG图片数据
  478. *
  479. * @return JPEG图片的数据.
  480. * @since V1.0
  481. */
  482. private byte[] getPictureOnJPEG() {
  483. if (null == mPlayerHandler) {
  484. Log.e(TAG, "getPictureOnJPEG():: mPlayerHandler is null");
  485. return null;
  486. }
  487. if (-1 == mPlayerPort) {
  488. Log.e(TAG, "getPictureOnJPEG():: mPlayerPort is Unavailable");
  489. return null;
  490. }
  491. int picSize = getPictureSize();
  492. if (picSize <= 0) {
  493. return null;
  494. }
  495. byte[] pictureBuffer = null;
  496. try {
  497. pictureBuffer = new byte[picSize];
  498. } catch (OutOfMemoryError e) {
  499. e.printStackTrace();
  500. pictureBuffer = null;
  501. return null;
  502. }
  503. Player.MPInteger jpgSize = new Player.MPInteger();
  504. boolean ret = mPlayerHandler.getJPEG(mPlayerPort, pictureBuffer, picSize, jpgSize);
  505. if (!ret) {
  506. Log.e(TAG, "getPictureOnJPEG():: mPlayerHandler.getJPEG() return false");
  507. return null;
  508. }
  509. int jpegSize = jpgSize.value;
  510. if (jpegSize <= 0) {
  511. pictureBuffer = null;
  512. return null;
  513. }
  514. ByteBuffer jpgBuffer = ByteBuffer.wrap(pictureBuffer, 0, jpegSize);
  515. if (null == jpgBuffer) {
  516. pictureBuffer = null;
  517. return null;
  518. }
  519. return jpgBuffer.array();
  520. }
  521. /**
  522. * 创建图片文件
  523. *
  524. * @param path 图片路径
  525. * @param fileName 图片名字
  526. * @return true - 图片创建成功 or false - 图片创建失败
  527. * @since V1.0
  528. */
  529. private boolean createPictureFile(String path, String fileName) {
  530. if (null == path || null == fileName || path.equals("") || fileName.equals("")) {
  531. return false;
  532. }
  533. String dirPath = createFileDir(path);
  534. if (null == dirPath || dirPath.equals("")) {
  535. return false;
  536. }
  537. try {
  538. mPictureFile = new File(dirPath + File.separator + fileName);
  539. if ((null != mPictureFile) && (!mPictureFile.exists())) {
  540. mPictureFile.createNewFile();
  541. }
  542. } catch (Exception e) {
  543. e.printStackTrace();
  544. mPictureFile = null;
  545. return false;
  546. }
  547. return true;
  548. }
  549. /**
  550. * 抓拍图片写到SDCard
  551. *
  552. * @param picData 图片数据
  553. * @param length 图片数据长度
  554. * @since V1.0
  555. */
  556. private boolean writePictureToFile(byte[] picData, int length) {
  557. if (null == picData || length <= 0 || picData.length > length) {
  558. return false;
  559. }
  560. if (null == mPictureFile) {
  561. return false;
  562. }
  563. FileOutputStream fOut = null;
  564. try {
  565. if (!mPictureFile.exists()) {
  566. mPictureFile.createNewFile();
  567. }
  568. fOut = new FileOutputStream(mPictureFile);
  569. fOut.write(picData, 0, length);
  570. fOut.flush();
  571. fOut.close();
  572. fOut = null;
  573. } catch (Exception e) {
  574. e.printStackTrace();
  575. fOut = null;
  576. mPictureFile.delete();
  577. mPictureFile = null;
  578. return false;
  579. }
  580. return true;
  581. }
  582. /**
  583. * 删除图片文件
  584. *
  585. * @since V1.0
  586. */
  587. private void removePictureFile() {
  588. try {
  589. if (null == mPictureFile) {
  590. return;
  591. }
  592. mPictureFile.delete();
  593. } catch (Exception e) {
  594. e.printStackTrace();
  595. } finally {
  596. mPictureFile = null;
  597. }
  598. }
  599. /**
  600. * 创建文件夹
  601. *
  602. * @param path 文件路径
  603. * @return 文件夹路径
  604. * @since V1.0
  605. */
  606. private String createFileDir(String path) {
  607. if (null == path || path.equals("")) {
  608. return "";
  609. }
  610. File tempFile = null;
  611. try {
  612. tempFile = new File(path);
  613. if ((null != tempFile) && (!tempFile.exists())) {
  614. tempFile.mkdirs();
  615. }
  616. } catch (Exception e) {
  617. e.printStackTrace();
  618. tempFile = null;
  619. return "";
  620. }
  621. return tempFile.getAbsolutePath();
  622. }
  623. /**
  624. * 停止录像 void
  625. *
  626. * @since V1.0
  627. */
  628. public void stopRecord() {
  629. if (!mIsRecord) {
  630. return;
  631. }
  632. mIsRecord = false;
  633. stopWriteStreamData();
  634. }
  635. /**
  636. * 停止写入数据流
  637. *
  638. * @since V1.0
  639. */
  640. private void stopWriteStreamData() {
  641. if (null == mRecordFileOutputStream) {
  642. return;
  643. }
  644. try {
  645. mRecordFileOutputStream.flush();
  646. mRecordFileOutputStream.close();
  647. } catch (IOException e) {
  648. e.printStackTrace();
  649. } finally {
  650. mRecordFileOutputStream = null;
  651. mRecordFile = null;
  652. }
  653. }
  654. /**
  655. * 启动录像方法
  656. *
  657. * @param filePath 录像文件路径
  658. * @param fileName 录像文件名称
  659. * @param isRpmPackage 是否启用转封装
  660. * @return true-启动录像成功,false-启动录像失败
  661. * @since V1.0
  662. */
  663. public boolean startRecord(String filePath, String fileName) {
  664. if (!UtilSDCard.isSDCardUsable()) {
  665. if (null != mLiveCallBack) {
  666. mLiveCallBack.onMessageCallback(ConstantLive.SD_CARD_UN_USEABLE);
  667. }
  668. return false;
  669. }
  670. if (UtilSDCard.getSDCardRemainSize() <= mSDCardSize) {
  671. if (null != mLiveCallBack) {
  672. mLiveCallBack.onMessageCallback(ConstantLive.SD_CARD_SIZE_NOT_ENOUGH);
  673. }
  674. return false;
  675. }
  676. if (LIVE_PLAY != mLiveState) {
  677. Log.e(TAG, "非播放状态不能录像");
  678. mLiveCallBack.onMessageCallback(ConstantLive.RECORD_FAILED_NPLAY_STATE);
  679. return false;
  680. }
  681. boolean ret = createRecordFile(filePath, fileName);
  682. if (!ret) {
  683. Log.e(TAG, "createRecordFile() fail 创建录像文件失败");
  684. return false;
  685. }
  686. ret = writeStreamHead(mRecordFile);
  687. if (!ret) {
  688. Log.e(TAG, "writeStreamHead() 写文件失败");
  689. removeRecordFile();
  690. return false;
  691. }
  692. mIsRecord = true;
  693. Log.e(TAG, "启动录像成功");
  694. return true;
  695. }
  696. /**
  697. * 创建录像文件
  698. *
  699. * @param path 文件路径
  700. * @param fileName 文件名
  701. * @return true - 创建成功 or false - 创建失败
  702. * @since V1.0
  703. */
  704. private boolean createRecordFile(String path, String fileName) {
  705. if (null == path || path.equals("") || null == fileName || fileName.equals("")) {
  706. return false;
  707. }
  708. try {
  709. mRecordFile = new File(path + File.separator + fileName);
  710. if ((null != mRecordFile) && (!mRecordFile.exists())) {
  711. mRecordFile.createNewFile();
  712. }
  713. } catch (IOException e) {
  714. e.printStackTrace();
  715. mRecordFile = null;
  716. return false;
  717. }
  718. return true;
  719. }
  720. /**
  721. * 写流头文件
  722. *
  723. * @param file 写入的文件
  724. * @return true - 写入头文件成功. false - 写入头文件失败.
  725. * @since V1.0
  726. */
  727. private boolean writeStreamHead(File file) {
  728. if (null == file || null == mStreamHeadDataBuffer) {
  729. Log.e("AAA", "mStreamHeadDataBuffer is null!");
  730. return false;
  731. }
  732. byte[] tempByte = mStreamHeadDataBuffer.array();
  733. if (null == tempByte) {
  734. return false;
  735. }
  736. try {
  737. if (null == mRecordFileOutputStream) {
  738. mRecordFileOutputStream = new FileOutputStream(file);
  739. }
  740. mRecordFileOutputStream.write(tempByte, 0, tempByte.length);
  741. } catch (Exception e) {
  742. e.printStackTrace();
  743. if (mRecordFileOutputStream != null) {
  744. try {
  745. mRecordFileOutputStream.close();
  746. } catch (IOException e1) {
  747. e1.printStackTrace();
  748. }
  749. }
  750. mRecordFileOutputStream = null;
  751. mStreamHeadDataBuffer = null;
  752. tempByte = null;
  753. return false;
  754. }
  755. return true;
  756. }
  757. /**
  758. * 删除录像文件
  759. *
  760. * @since V1.0
  761. */
  762. private void removeRecordFile() {
  763. try {
  764. if (null == mRecordFile) {
  765. return;
  766. }
  767. mRecordFile.delete();
  768. } catch (Exception e) {
  769. e.printStackTrace();
  770. } finally {
  771. mRecordFile = null;
  772. }
  773. }
  774. /**
  775. * 开启音频
  776. *
  777. * @return boolean
  778. * @since V1.0
  779. */
  780. public boolean startAudio() {
  781. if (LIVE_PLAY != mLiveState) {
  782. Log.e(TAG, "非播放状态不能开启音频");
  783. mLiveCallBack.onMessageCallback(ConstantLive.AUDIO_START_FAILED_NPLAY_STATE);
  784. return false;
  785. }
  786. if (null == mPlayerHandler) {
  787. return false;
  788. }
  789. boolean ret = mPlayerHandler.playSound(mPlayerPort);
  790. if (!ret) {
  791. return false;
  792. }
  793. return true;
  794. }
  795. /**
  796. * 关闭音频
  797. *
  798. * @return boolean
  799. * @since V1.0
  800. */
  801. public boolean stopAudio() {
  802. if (LIVE_PLAY != mLiveState) {
  803. Log.e(TAG, "非播放状态不能关闭音频");
  804. return false;
  805. }
  806. if (null == mPlayerHandler) {
  807. return false;
  808. }
  809. boolean ret = mPlayerHandler.stopSound();
  810. if (!ret) {
  811. return false;
  812. }
  813. return true;
  814. }
  815. /**
  816. * 获取JPEG图片大小
  817. *
  818. * @return JPEG图片的大小.
  819. * @throws PlayerException
  820. * @throws MediaPlayerException MediaPlayer 异常
  821. * @since V1.0
  822. */
  823. private int getPictureSize() {
  824. Player.MPInteger width = new Player.MPInteger();
  825. Player.MPInteger height = new Player.MPInteger();
  826. boolean ret = mPlayerHandler.getPictureSize(mPlayerPort, width, height);
  827. if (!ret) {
  828. Log.e(TAG, "getPictureSize():: mPlayerHandler.getPictureSize() return false,errorCode is P"
  829. + mPlayerHandler.getLastError(mPlayerPort));
  830. return 0;
  831. }
  832. int pictureSize = width.value * height.value * 3;
  833. return pictureSize;
  834. }
  835. /**
  836. * 向播放库塞数据
  837. *
  838. * @param data
  839. * @param len void
  840. * @since V1.0
  841. */
  842. private void processStreamData(byte[] data, int len) {
  843. if (null == data || 0 == len) {
  844. Log.e(TAG, "processStreamData() Stream data is null or len is 0");
  845. return;
  846. }
  847. if (null != mPlayerHandler) {
  848. boolean ret = mPlayerHandler.inputData(mPlayerPort, data, len);
  849. if (!ret) {
  850. SystemClock.sleep(10);
  851. }
  852. }
  853. }
  854. /*
  855. * handle - - 引擎id opt - -回调消息,包括:RTSPCLIENT_MSG_PLAYBACK_FINISH,RTSPCLIENT_MSG_BUFFER_OVERFLOW
  856. * ,RTSPCLIENT_MSG_CONNECTION_EXCEPTION 三种 param1 - - 保留参数 param2 - - 保留参数 useId - - 用户数据,默认就是引擎id与handle相同
  857. */
  858. @Override
  859. public void onMessageCallBack(int handle, int opt, int param1, int param2, int useId) {
  860. if (opt == RtspClient.RTSPCLIENT_MSG_CONNECTION_EXCEPTION) {
  861. stop();
  862. Log.e(TAG, "onMessageCallBack():: rtsp connection exception");
  863. if (connectNum > 3) {
  864. Log.e(TAG, "onMessageCallBack():: rtsp connection more than three times");
  865. connectNum = 0;
  866. } else {
  867. startLive(mSurfaceView);
  868. connectNum++;
  869. }
  870. }
  871. }
  872. /**
  873. * 返回已经播放的流量 void
  874. *
  875. * @return long
  876. * @since V1.0
  877. */
  878. public long getStreamRate() {
  879. return mStreamRate;
  880. }
  881. /**
  882. * 清空流量统计 void
  883. *
  884. * @since V1.0
  885. */
  886. public void clearStreamRate() {
  887. mStreamRate = 0;
  888. }
  889. /**
  890. * 获取OSD时间
  891. *
  892. * @return Calendar
  893. * @since V1.0
  894. */
  895. public Calendar getOSDTime() {
  896. Calendar systemTime = Calendar.getInstance();
  897. if (null == mPlayerHandler) {
  898. Log.e(TAG, "getOSDTime(): mPlayerHandler is null!");
  899. return null;
  900. }
  901. if (-1 == mPlayerPort) {
  902. Log.e(TAG, "getOSDTime(): mPlayerPort is -1");
  903. return null;
  904. }
  905. MPSystemTime time = new MPSystemTime();
  906. boolean ret = mPlayerHandler.getSystemTime(mPlayerPort, time);
  907. if (!ret) {
  908. Log.e(TAG,
  909. "getOSDTime(): getSystemTime() fail errorCode is " + mPlayerHandler.getLastError(mPlayerPort));
  910. mLiveCallBack.onMessageCallback(ConstantLive.GET_OSD_TIME_FAIL);
  911. return systemTime;
  912. }
  913. systemTime.set(Calendar.YEAR, time.year);
  914. systemTime.set(Calendar.MONTH, time.month - 1);
  915. systemTime.set(Calendar.DAY_OF_MONTH, time.day);
  916. systemTime.set(Calendar.HOUR_OF_DAY, time.hour);
  917. systemTime.set(Calendar.MINUTE, time.min);
  918. systemTime.set(Calendar.SECOND, time.sec);
  919. systemTime.set(Calendar.MILLISECOND, time.ms);
  920. return systemTime;
  921. }
  922. @Override
  923. public void onDisplay(int arg0, byte[] arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7) {
  924. if (LIVE_PLAY != mLiveState) {
  925. mLiveState = LIVE_PLAY;
  926. if (null != mLiveCallBack) {
  927. mLiveCallBack.onMessageCallback(ConstantLive.PLAY_DISPLAY_SUCCESS);
  928. } else {
  929. Log.e(TAG, "onDisplay():: mLiveCallBack is null");
  930. }
  931. }
  932. }
  933. }