MusicPlayer.cpp 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145
  1. #include "MusicPlayer.h"
  2. #include "DeviceWatcher/DeviceWatcher.h"
  3. #include "AutoConnect.h"
  4. #include "Utility.h"
  5. #include "UserInterfaceUtility.h"
  6. #include "MusicInformation/MusicInformation.h"
  7. #include <QTimer>
  8. #include <QDBusConnection>
  9. #include <QProcess>
  10. #include <QDir>
  11. #include <QFile>
  12. #include <QTextStream>
  13. #include <QFileInfo>
  14. #include <QDomDocument>
  15. #include <iostream>
  16. #include <stdio.h>
  17. #include <unistd.h>
  18. #include <pthread.h>
  19. #include <fcntl.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <QDebug>
  23. #include <arpa/inet.h> //for in_addr
  24. #include <linux/rtnetlink.h> //for rtnetlink
  25. #include <net/if.h> //for IF_NAMESIZ, route_info
  26. #include <QFile>
  27. #include <pthread.h>
  28. #include<sys/types.h>
  29. #include<sys/stat.h>
  30. #include<sys/wait.h>
  31. #include<semaphore.h>
  32. #include <errno.h>
  33. #include "configUtils.h"
  34. using namespace std;
  35. static const string SDMultimedia("/data/MultiMediaFile/SDMultimedia");
  36. static const string SDMusicMillesmial("/data/MultiMediaFile/SDMusicMillesmial");
  37. static const string SDMusicPathInfo("/data/MultiMediaFile/SDMusicPathInfo");
  38. static const string USBMultimedia("/data/MultiMediaFile/USBMultimedia");
  39. static const string USBMusicMillesmial("/data/MultiMediaFile/USBMusicMillesmial");
  40. static const string USBMusicPathInfo("/data/MultiMediaFile/USBMusicPathInfo");
  41. int getCrrentMusicPlayMode()
  42. {
  43. QFile file("/etc/playmode");
  44. if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
  45. {
  46. qDebug()<<Q_FUNC_INFO<<"file :/etc/playmode is open failed";
  47. return 0;
  48. }
  49. QTextStream in(&file);
  50. QString line = in.readLine();
  51. qDebug() << __PRETTY_FUNCTION__<<line.toInt();
  52. file.flush();
  53. file.close();
  54. if(line.isEmpty()){
  55. return 0;
  56. }
  57. return line.toInt();
  58. }
  59. class MusicPlayerPrivate
  60. {
  61. Q_DISABLE_COPY(MusicPlayerPrivate)
  62. public:
  63. explicit MusicPlayerPrivate(MusicPlayer *parent);
  64. ~MusicPlayerPrivate();
  65. void connectAllSlots();
  66. QList<QString>& getPathList(const DeviceWatcherType type);
  67. void seekToMillesimal(const int millesimal);
  68. void setPlayStatus(const MusicPlayerPlayStatus status);
  69. void setPlayMode(const MusicPlayerPlayMode mode);
  70. void pauseToggleHandler(const QString& output);
  71. void timeLengthHandler(const QString &output);
  72. void millesimalHandler(const QString& output);
  73. void timePositionHandler(const QString &output);
  74. void quitHandler();
  75. void stopHandler();
  76. void endOfFileHandler();
  77. void unsupportHandler();
  78. void exitMusicPlayer();
  79. void createUSBFileNamesXml();
  80. void createSDFileNamesXml();
  81. void musicPlayerSetPlay();
  82. void musicPlayerSetPause();
  83. void musicPlayerSetStop();
  84. void musicPlayerSetExit(const DeviceWatcherType type);
  85. void musicPlayerPlayStatus(int type,int status);
  86. void writeCmdToMplayer(char* cmd);
  87. void quitMpalyer();
  88. QString chgform(QString name);
  89. ssize_t readLine(int fd, char *buffer, size_t n);
  90. MusicPlayerPlayMode m_PlayMode;
  91. MusicPlayerPlayStatus m_PlayStatus;
  92. QList<QString> m_USBPathList;
  93. QList<QString> m_SDPathList;
  94. QString m_USBFileNamesXml;
  95. QString m_SDFileNamesXml;
  96. QStringList m_USBFileArtistList;
  97. QStringList m_SdFileArtistList;
  98. DeviceWatcherType m_DiskType;
  99. QString m_CurrentFilePath;
  100. MusicInformation m_MusicInformation;
  101. int m_PlayIndex;
  102. int m_ElapsedTime;
  103. int m_EndTime;
  104. int m_Millesimal;
  105. int m_ReadpThread;
  106. int fd[2];
  107. int m_Fd_w;
  108. bool m_IsRunning;
  109. pid_t m_pid1;
  110. pid_t m_pid2;
  111. private:
  112. Q_DECLARE_PUBLIC(MusicPlayer)
  113. MusicPlayer* const q_ptr;
  114. };
  115. static void* readyReadStandardOutput(void* arg)
  116. {
  117. MusicPlayerPrivate* pThis = (MusicPlayerPrivate*)arg;
  118. char info[512] = {0};
  119. int ret = 0;
  120. while (1) {
  121. if(pThis->m_ReadpThread == 0)
  122. {
  123. qDebug()<<"+++[MusicPlayer::readyReadStandardOutput:pThis->m_ReadpThread]+++"<<pThis->m_ReadpThread;
  124. break;//退出线程
  125. }
  126. bzero(info, 512);
  127. ret = pThis->readLine(pThis->fd[0], info, 512);
  128. while(ret > 0)
  129. {
  130. string str(info);
  131. QString output = QString::fromStdString(str);
  132. //qDebug()<<"mplayer music:"<<output;
  133. //音频的长度,时间长度
  134. if (output.contains(QString("ANS_LENGTH="))) {
  135. pThis->timeLengthHandler(output);
  136. }
  137. //音频播放位置的百分比
  138. else if (output.contains(QString("ANS_PERCENT_POSITION="))) {
  139. pThis->millesimalHandler(output);
  140. }
  141. //音频播放的时间点
  142. else if (output.contains(QString("ANS_TIME_POSITION="))) {
  143. pThis->timePositionHandler(output);
  144. }
  145. //音频暂停与播放切换成功与否
  146. else if (output.contains(QString("ANS_pause"))) {
  147. pThis->pauseToggleHandler(output);
  148. }
  149. //音频播放完成
  150. else if (output.contains(QString("EOF code: 1"))) {
  151. sleep(2);
  152. pThis->setPlayStatus(MPPS_Stop);
  153. pThis->endOfFileHandler();
  154. }
  155. else if (output.contains(QString("EOF code: 4"))
  156. || (output.contains(QString("EOF code: 2")))) {
  157. pThis->stopHandler();
  158. }
  159. //不支持的音频
  160. else if ((output.contains(QString("incorrect streams")))
  161. || (output.contains(QString("No stream found")))){
  162. sleep(2);
  163. pThis->unsupportHandler();
  164. }/* else if (output.contains(QString("seek-begin"))) {
  165. } *///进度条改变播放完成
  166. else if ((output.contains(QString("seek-finish"))
  167. || (output.contains(QString("seek-error"))))) {
  168. pThis->musicPlayerPlayStatus(pThis->m_DiskType, MPPS_SeekFinish);
  169. }
  170. else{
  171. if(output != "\n")
  172. qDebug()<<"output:"<<output;
  173. }
  174. bzero(info, 512);
  175. ret = pThis->readLine(pThis->fd[0], info, 512);
  176. }
  177. if(ret <= 0){
  178. sleep(1);
  179. }
  180. }
  181. close(pThis->fd[0]);
  182. pThis->m_IsRunning = false;
  183. if(pThis->m_Fd_w > 0)
  184. {
  185. close(pThis->m_Fd_w);
  186. pThis->m_Fd_w = -1;
  187. }
  188. pThis->m_pid2 = wait(NULL);//回收mpalyer的进程号,避免mpalyer成为僵尸进程
  189. printf("*********MusicPlayer_pid2= %d \n",pThis->m_pid2);//wait的返回值为子进程的pid
  190. return NULL;
  191. }
  192. void MusicPlayer::musicPlayerRequestFileNames(const DeviceWatcherType type)
  193. {
  194. Q_D(MusicPlayer);
  195. switch (type) {
  196. case DWT_SDDisk: {
  197. emit onMusicPlayerFileNames(DWT_SDDisk, d->m_SDFileNamesXml);
  198. break;
  199. }
  200. case DWT_USBDisk: {
  201. emit onMusicPlayerFileNames(DWT_USBDisk, d->m_USBFileNamesXml);
  202. break;
  203. }
  204. default: {
  205. break;
  206. }
  207. }
  208. }
  209. void MusicPlayer::musicPlayerSetPlayModeToggle()
  210. {
  211. Q_D(MusicPlayer);
  212. switch (d->m_PlayMode) {
  213. case MPPM_AllRepeat: {
  214. musicPlayerSetPlayMode(MPPM_Shuffle);
  215. break;
  216. }
  217. case MPPM_Shuffle: {
  218. musicPlayerSetPlayMode(MPPM_RepeatOnce);
  219. break;
  220. }
  221. case MPPM_RepeatOnce:
  222. default: {
  223. musicPlayerSetPlayMode(MPPM_AllRepeat);
  224. break;
  225. }
  226. }
  227. }
  228. void MusicPlayer::musicPlayerSetPlayMode(const MusicPlayerPlayMode mode)
  229. {
  230. Q_D(MusicPlayer);
  231. d->setPlayMode(mode);
  232. }
  233. void MusicPlayer::musicPlayerSetPlayStatusToggle()
  234. {
  235. Q_D(MusicPlayer);
  236. qDebug()<<"++++++++d->m_PlayStatus+++++++"<<d->m_PlayStatus;
  237. switch (d->m_PlayStatus) {
  238. case MPPS_Play: {
  239. musicPlayerSetPlayStatus(MPPS_Pause);
  240. break;
  241. }
  242. case MPPS_Unsupport: {
  243. playMusicIndex(d->m_DiskType, d->m_PlayIndex, 0);
  244. break;
  245. }
  246. case MPPS_Pause:
  247. default: {
  248. musicPlayerSetPlayStatus(MPPS_Play);
  249. break;
  250. }
  251. }
  252. }
  253. void MusicPlayer::musicPlayerSetPlayStatus(const MusicPlayerPlayStatus status)
  254. {
  255. Q_D(MusicPlayer);
  256. switch (status) {
  257. case MPPS_Play: {
  258. d->musicPlayerSetPlay();
  259. break;
  260. }
  261. case MPPS_Pause: {
  262. d->musicPlayerSetPause();
  263. break;
  264. }
  265. case MPPS_Stop: {
  266. d->musicPlayerSetStop();
  267. break;
  268. }
  269. case MPPS_Exit: {
  270. break;
  271. }
  272. default : {
  273. break;
  274. }
  275. }
  276. }
  277. void MusicPlayer::musicPlayerPlayListViewIndex(const DeviceWatcherType type, const int index, const int millesimal)
  278. {
  279. Q_D(MusicPlayer);
  280. playMusicIndex(type, index, millesimal);
  281. }
  282. void MusicPlayer::musicPlayerPlayPreviousListViewIndex()
  283. {
  284. Q_D(MusicPlayer);
  285. int lastIndex;
  286. if (MPPM_Shuffle == d->m_PlayMode) {
  287. lastIndex = qrand() % d->getPathList( d->m_DiskType).size();
  288. } else {
  289. lastIndex = d->m_PlayIndex;
  290. if ((lastIndex > 0)
  291. && (lastIndex <= d->getPathList( d->m_DiskType).size() - 1)) {
  292. --lastIndex;
  293. } else {
  294. lastIndex = d->getPathList( d->m_DiskType).size() - 1;
  295. }
  296. }
  297. musicPlayerPlayListViewIndex( d->m_DiskType, lastIndex, 0);
  298. }
  299. void MusicPlayer::musicPlayerPlayNextListViewIndex()
  300. {
  301. Q_D(MusicPlayer);
  302. int lastIndex;
  303. if (MPPM_Shuffle == d->m_PlayMode) {
  304. lastIndex = qrand() % d->getPathList(d->m_DiskType).size();
  305. } else {
  306. lastIndex = d->m_PlayIndex;
  307. if ((lastIndex < (d->getPathList(d->m_DiskType).size() - 1))
  308. && (lastIndex >= 0)) {
  309. ++lastIndex;
  310. } else {
  311. lastIndex = 0;
  312. }
  313. }
  314. musicPlayerPlayListViewIndex(d->m_DiskType, lastIndex, 0);
  315. }
  316. void MusicPlayer::musicPlayerSeekToMillesimal(const int millesimal)
  317. {
  318. Q_D(MusicPlayer);
  319. if (d->m_IsRunning) {
  320. d->seekToMillesimal(millesimal);
  321. }
  322. }
  323. void MusicPlayer::musicPlayerExit()
  324. {
  325. Q_D(MusicPlayer);
  326. d->musicPlayerSetExit(d->m_DiskType);
  327. }
  328. void MusicPlayer::onDeviceWatcherStatus(const DeviceWatcherType type, const DeviceWatcherStatus status)
  329. {
  330. Q_D(MusicPlayer);
  331. if (DWT_SDDisk == type) {
  332. switch (status) {
  333. case DWS_Empty: {
  334. d->m_SDPathList.clear();
  335. d->m_SdFileArtistList.clear();
  336. break;
  337. }
  338. case DWS_Busy: {
  339. d->m_SDPathList.clear();
  340. d->m_SdFileArtistList.clear();
  341. break;
  342. }
  343. case DWS_Ready: {
  344. d->createSDFileNamesXml();
  345. musicPlayerRequestFileNames(DWT_SDDisk);
  346. emit onMusicPlayerFileArtist(DWT_SDDisk,d->m_SdFileArtistList);
  347. break;
  348. }
  349. case DWS_Remove: {
  350. d->m_SDPathList.clear();
  351. d->m_SdFileArtistList.clear();
  352. if (DWT_SDDisk == d->m_DiskType) {
  353. if (d->m_IsRunning) {
  354. d->quitMpalyer();
  355. }
  356. d->setPlayStatus(MPPS_Exit);
  357. }
  358. break;
  359. }
  360. default : {
  361. break;
  362. }
  363. }
  364. } else if (DWT_USBDisk == type) {
  365. switch (status) {
  366. case DWS_Empty: {
  367. d->m_USBPathList.clear();
  368. d->m_USBFileArtistList.clear();
  369. break;
  370. }
  371. case DWS_Busy: {
  372. d->m_USBPathList.clear();
  373. d->m_USBFileArtistList.clear();
  374. break;
  375. }
  376. case DWS_Ready: {
  377. d->createUSBFileNamesXml();
  378. musicPlayerRequestFileNames(DWT_USBDisk);
  379. emit onMusicPlayerFileArtist(DWT_USBDisk,d->m_USBFileArtistList);
  380. break;
  381. }
  382. case DWS_Remove: {
  383. d->m_USBPathList.clear();
  384. d->m_USBFileArtistList.clear();
  385. if (DWT_USBDisk == d->m_DiskType) {
  386. if (d->m_IsRunning) {
  387. d->quitMpalyer();
  388. }
  389. d->setPlayStatus(MPPS_Exit);
  390. }
  391. break;
  392. }
  393. default : {
  394. break;
  395. }
  396. }
  397. }
  398. }
  399. void MusicPlayer::onMusicFilePath(const QString &path, const DeviceWatcherType type)
  400. {
  401. Q_D(MusicPlayer);
  402. if (DWT_USBDisk == type) {
  403. d->m_USBPathList.append(path);
  404. } else if (DWT_SDDisk == type) {
  405. d->m_SDPathList.append(path);
  406. }
  407. }
  408. void MusicPlayer::onTimeout()
  409. {
  410. Q_D(MusicPlayer);
  411. d->endOfFileHandler();
  412. }
  413. void MusicPlayer::playMusicIndex(const DeviceWatcherType type, const int index, const int millesimal)
  414. {
  415. Q_D(MusicPlayer);
  416. QList<QString> temp = d->getPathList(type);
  417. qDebug()<<"+++[MusicPlayer::playMusicIndex]+++";
  418. if ((temp.size() > index)
  419. && (QFile(temp.at(index))).exists()) {
  420. d->m_CurrentFilePath = temp.at(index);
  421. d->m_DiskType = type;
  422. d->m_ElapsedTime = 0;
  423. d->m_EndTime = 0;
  424. d->m_PlayIndex = index;
  425. d->m_Millesimal = 0;
  426. //qDebug()<<
  427. //启动一个上一次播放过的音频,如果mplayer已经启动,则先退出mplayer
  428. if (0 != millesimal) {
  429. if(d->m_IsRunning)
  430. {
  431. d->quitMpalyer();
  432. sleep(2);//等待mplayer完全退出,m_IsRunning置为false
  433. }
  434. }
  435. d->m_DiskType = type;
  436. if (d->m_IsRunning == false){
  437. //创建一个有名管道/data/pipe,如果不存在直接创建,存在则先删除再创建
  438. if(access("/data/pipe",F_OK) != 0)
  439. {
  440. printf("pipe not exist\n");
  441. mkfifo("/data/pipe",0777);
  442. }
  443. else{
  444. unlink("/data/pipe");
  445. mkfifo("/data/pipe", 0777);
  446. }
  447. //初始化无名管道,这步不能少
  448. if(pipe(d->fd) < 0){
  449. perror("pipe error\n");
  450. return;
  451. }
  452. fcntl(d->fd[0], F_SETFL, O_NONBLOCK); //无名管道设为非阻塞
  453. d->m_pid1 = vfork();//创建一个子进程,用来启动mplayer进程
  454. printf("+++++++++00000Music_pid++++++++\n");
  455. if(d->m_pid1 < 0){
  456. perror("fork error\n");
  457. }
  458. else if(d->m_pid1 == 0)
  459. {
  460. printf("child:video0000%d\n",getpid());
  461. close(d->fd[0]);
  462. dup2(d->fd[1], STDERR_FILENO);//将该子进程的标准输出重定向到无名管道,也就是把mplayer的标准输出重定向到无名管道
  463. QByteArray _NameByte = d->m_CurrentFilePath.toLocal8Bit();
  464. const char* _Name = _NameByte.data();
  465. if(millesimal == 0){
  466. //启动一个从头开始播放音频的mplayer进程 "-input", "file=/data/pipe"是通知mplayer使用该有名管道通信
  467. execlp("/usr/bin/mplayer", "mplayer", "-slave", "-quiet", "-idle","-novideo","-input","file=/data/pipe", _Name,NULL); //命名管道pipe有命令数据,mplayer会自动读取
  468. }
  469. else{
  470. //启动一个从固定位置播放音频的mplayer进程
  471. const char* _ChMillesimal = std::to_string(millesimal).c_str();
  472. execlp("/usr/bin/mplayer", "mplayer", "-slave", "-quiet", "-idle","-novideo","-input","file=/data/pipe","-ss",_ChMillesimal,_Name,NULL);
  473. }
  474. }
  475. else{
  476. emit onMusicPlayerPlayMode(d->m_PlayMode);
  477. d->m_PlayStatus = MPPS_Start;
  478. emit onMusicPlayerPlayStatus(d->m_DiskType, d->m_PlayStatus);
  479. QFileInfo fileInfo(d->m_CurrentFilePath);
  480. d->m_MusicInformation.parserFilePath(d->m_CurrentFilePath);
  481. emit onMusicPlayerElapsedInformation(d->m_ElapsedTime, d->m_Millesimal);
  482. emit onMusicPlayerID3TagChange(d->m_DiskType,
  483. d->m_PlayIndex,
  484. fileInfo.filePath(),
  485. d->m_MusicInformation.getTitle(),
  486. d->m_MusicInformation.getArtist(),
  487. d->m_MusicInformation.getAlbum(),
  488. d->m_EndTime);
  489. QString filePath = fileInfo.filePath() + QString("/") +
  490. fileInfo.created().toString(QString("yyyyMMddhhmmss")) +
  491. fileInfo.lastModified().toString(QString("yyyyMMddhhmmss")) +
  492. QString::number(fileInfo.size());
  493. int value = MT_Music;
  494. if(d->m_DiskType == DWT_USBDisk){
  495. SaveConfigString(filePath.toStdString(),USBMusicPathInfo);
  496. system("sync");
  497. SaveConfigString(value,USBMultimedia);
  498. system("sync");
  499. }
  500. else if(d->m_DiskType == DWT_SDDisk){
  501. SaveConfigString(filePath.toStdString(),SDMusicPathInfo);
  502. system("sync");
  503. SaveConfigString(value,SDMultimedia);
  504. system("sync");
  505. }
  506. d->m_ReadpThread = 1;//线程退出标志
  507. close(d->fd[1]);
  508. usleep(200*1000);
  509. d->m_IsRunning = true;
  510. pthread_t pthead;
  511. int ret = pthread_create(&pthead, NULL,readyReadStandardOutput,d);//创建一个线程用来读取mplayer的标准输出
  512. if(ret != 0) {
  513. printf("pthread_create failed!\n");
  514. }
  515. }
  516. }
  517. else{
  518. //加载音频项到mplayer
  519. char pathname[512] = {0};
  520. strcat(pathname, "loadfile ");
  521. QString _FilePath = d->chgform(d->m_CurrentFilePath);
  522. //qDebug()<<"++++filePath000+++++"<< _FilePath;
  523. QByteArray _NameByte = _FilePath.toLocal8Bit();
  524. char* _Name = _NameByte.data();
  525. strcat(pathname, _Name);
  526. strcat(pathname, "\n");
  527. printf("+++++++++++++m_Fd_w_pathname:%s", pathname);
  528. //使用有名管道/data/pipe向mplayer发送命令
  529. if(d->m_Fd_w < 0)
  530. {
  531. d->m_Fd_w = open("/data/pipe",O_WRONLY| O_NONBLOCK | O_TRUNC);
  532. if(d->m_Fd_w < 0)
  533. {
  534. perror("open file error");
  535. d->m_ReadpThread = 0;
  536. return;
  537. }
  538. }
  539. ftruncate(d->m_Fd_w,0);
  540. lseek(d->m_Fd_w,0,SEEK_SET);
  541. write(d->m_Fd_w, pathname, strlen(pathname));
  542. //这些是与UI界面通信的代码
  543. emit onMusicPlayerPlayMode(d->m_PlayMode);
  544. d->m_PlayStatus = MPPS_Start;
  545. emit onMusicPlayerPlayStatus(d->m_DiskType, d->m_PlayStatus);
  546. QFileInfo fileInfo(d->m_CurrentFilePath);
  547. d->m_MusicInformation.parserFilePath(d->m_CurrentFilePath);
  548. emit onMusicPlayerElapsedInformation(d->m_ElapsedTime, d->m_Millesimal);
  549. emit onMusicPlayerID3TagChange(d->m_DiskType,
  550. d->m_PlayIndex,
  551. fileInfo.filePath(),
  552. d->m_MusicInformation.getTitle(),
  553. d->m_MusicInformation.getArtist(),
  554. d->m_MusicInformation.getAlbum(),
  555. d->m_EndTime);
  556. QString filePath = fileInfo.filePath() + QString("/") +
  557. fileInfo.created().toString(QString("yyyyMMddhhmmss")) +
  558. fileInfo.lastModified().toString(QString("yyyyMMddhhmmss")) +
  559. QString::number(fileInfo.size());
  560. int value = MT_Music;
  561. if(d->m_DiskType == DWT_USBDisk){
  562. SaveConfigString(filePath.toStdString(),USBMusicPathInfo);
  563. system("sync");
  564. SaveConfigString(value,USBMultimedia);
  565. system("sync");
  566. }
  567. else if(d->m_DiskType == DWT_SDDisk){
  568. SaveConfigString(filePath.toStdString(),SDMusicPathInfo);
  569. system("sync");
  570. SaveConfigString(value,SDMultimedia);
  571. system("sync");
  572. }
  573. }
  574. }
  575. }
  576. MusicPlayer::MusicPlayer(QObject *parent)
  577. : QObject(parent)
  578. , d_ptr(new MusicPlayerPrivate(this))
  579. {
  580. }
  581. MusicPlayer::~MusicPlayer()
  582. {
  583. }
  584. MusicPlayerPrivate::MusicPlayerPrivate(MusicPlayer *parent)
  585. : q_ptr(parent)
  586. {
  587. m_ReadpThread = 1;
  588. m_IsRunning = false;
  589. m_Fd_w = -1;
  590. connectAllSlots();
  591. m_PlayMode = getCrrentMusicPlayMode();
  592. }
  593. MusicPlayerPrivate::~MusicPlayerPrivate()
  594. {
  595. if (m_IsRunning) {
  596. quitMpalyer();
  597. }
  598. }
  599. void MusicPlayerPrivate::connectAllSlots()
  600. {
  601. Q_Q(MusicPlayer);
  602. connectSignalAndSlotByNamesake(g_DeviceWatcher, q, SLOT(onDeviceWatcherStatus(const int, const int)));
  603. connectSignalAndSlotByNamesake(g_DeviceWatcher, q, SLOT(onMusicFilePath(const QString &, const int)));
  604. }
  605. QList<QString> &MusicPlayerPrivate::getPathList(const int type)
  606. {
  607. switch (type) {
  608. case DWT_SDDisk: {
  609. return m_SDPathList;
  610. break;
  611. }
  612. case DWT_USBDisk:
  613. default: {
  614. return m_USBPathList;
  615. break;
  616. }
  617. }
  618. }
  619. void MusicPlayerPrivate::seekToMillesimal(const int millesimal)
  620. {
  621. Q_Q(MusicPlayer);
  622. if ((MPPS_Play == m_PlayStatus)
  623. || (MPPS_Pause == m_PlayStatus)) {
  624. QString cmd("seek %1.%2 1\n");
  625. cmd = cmd.arg(millesimal / 10, 3, 10, QChar(' ')).arg(millesimal % 10, 1, 10, QChar('0'));
  626. QByteArray ba = cmd.toLatin1(); // must
  627. char* ch;
  628. ch=ba.data();
  629. writeCmdToMplayer(ch);//改变播放时间点,也可以用来实现快进和快退
  630. setPlayStatus(MPPS_Play);
  631. } else if (MPPS_Stop == m_PlayStatus) {
  632. q->playMusicIndex(m_DiskType, m_PlayIndex, 0);
  633. }
  634. }
  635. void MusicPlayerPrivate::setPlayStatus(const MusicPlayerPlayStatus status)
  636. {
  637. Q_Q(MusicPlayer);
  638. if (status != m_PlayStatus) {
  639. m_PlayStatus = status;
  640. }
  641. emit q->onMusicPlayerPlayStatus(m_DiskType, m_PlayStatus);
  642. }
  643. void MusicPlayerPrivate::setPlayMode(const MusicPlayerPlayMode mode)
  644. {
  645. Q_Q(MusicPlayer);
  646. if (mode != m_PlayMode) {
  647. m_PlayMode = mode;
  648. }
  649. emit q->onMusicPlayerPlayMode(m_PlayMode);
  650. }
  651. void MusicPlayerPrivate::pauseToggleHandler(const QString &output)
  652. {
  653. if (output.contains(QString("yes"))) {
  654. setPlayStatus(MPPS_Pause);
  655. } else if (output.contains(QString("no"))) {
  656. setPlayStatus(MPPS_Play);
  657. }
  658. }
  659. void MusicPlayerPrivate::timeLengthHandler(const QString &output)
  660. {
  661. Q_Q(MusicPlayer);
  662. int start = output.indexOf(QChar('=')) + 1;
  663. int end = output.indexOf(QChar('\n'));
  664. if ((-1 != start)
  665. && (-1 != end)) {
  666. m_EndTime = static_cast<int>(output.mid(start, end - start).toFloat());
  667. } else {
  668. m_EndTime = 0;
  669. }
  670. QFileInfo fileInfo(m_CurrentFilePath);
  671. m_MusicInformation.parserFilePath(m_CurrentFilePath);
  672. //qDebug()<<"++++++++++timeLengthHandler++++++++++++";
  673. emit q->onMusicPlayerID3TagChange(m_DiskType,
  674. m_PlayIndex,
  675. fileInfo.filePath(),
  676. m_MusicInformation.getTitle(),
  677. m_MusicInformation.getArtist(),
  678. m_MusicInformation.getAlbum(),
  679. m_EndTime);
  680. m_PlayStatus = MPPS_Play;
  681. emit q->onMusicPlayerPlayStatus(m_DiskType, m_PlayStatus);
  682. }
  683. void MusicPlayerPrivate::millesimalHandler(const QString &output)
  684. {
  685. int start = output.indexOf(QChar('=')) + 1;
  686. int end = output.indexOf(QChar('\n'));
  687. if ((-1 != start)
  688. && (-1 != end)) {
  689. bool ok(false);
  690. int millesimal = static_cast<int>(output.mid(start, end - start).toFloat(&ok) * 1000);
  691. if (ok) {
  692. m_Millesimal = millesimal;
  693. }
  694. }
  695. }
  696. void MusicPlayerPrivate::timePositionHandler(const QString &output)
  697. {
  698. Q_Q(MusicPlayer);
  699. if (output.startsWith(QString("ANS_TIME_POSITION="), Qt::CaseSensitive)) {
  700. int start = output.indexOf(QChar('=')) + 1;
  701. int end = output.indexOf(QChar('\n'));
  702. if ((-1 != start)
  703. && (-1 != end)) {
  704. bool ok(false);
  705. int elapsed = output.mid(start, end - start).toInt(&ok);
  706. if (ok) {
  707. if (((qAbs(m_ElapsedTime - elapsed) > 5))
  708. || (elapsed % 5)) {
  709. if(m_DiskType == DWT_USBDisk){
  710. SaveConfigString(elapsed,USBMusicMillesmial);
  711. system("sync");
  712. }
  713. else if(m_DiskType == DWT_SDDisk){
  714. SaveConfigString(elapsed,SDMusicMillesmial);
  715. system("sync");
  716. }
  717. }
  718. m_ElapsedTime = elapsed;
  719. }
  720. }
  721. emit q->onMusicPlayerElapsedInformation(m_ElapsedTime, m_Millesimal);
  722. }
  723. }
  724. void MusicPlayerPrivate::quitHandler()
  725. {
  726. setPlayStatus(MPPS_Exit);
  727. }
  728. void MusicPlayerPrivate::stopHandler()
  729. {
  730. Q_Q(MusicPlayer);
  731. m_ElapsedTime = 0;
  732. m_Millesimal = 0;
  733. setPlayStatus(MPPS_Stop);
  734. emit q->onMusicPlayerElapsedInformation(m_ElapsedTime, m_Millesimal);
  735. }
  736. void MusicPlayerPrivate::endOfFileHandler()
  737. {
  738. //qDebug()<<"+++++++endOfFileHandler+++++++";
  739. Q_Q(MusicPlayer);
  740. switch (m_PlayStatus) {
  741. case MPPS_Start:
  742. case MPPS_Unsupport:
  743. case MPPS_Pause:
  744. case MPPS_Stop:
  745. case MPPS_Play: {
  746. switch (m_PlayMode) {
  747. case MPPM_AllRepeat: {
  748. if ((getPathList(m_DiskType).size() - 1) > m_PlayIndex) {
  749. ++m_PlayIndex;
  750. } else {
  751. m_PlayIndex = 0;
  752. }
  753. break;
  754. }
  755. case MPPM_RepeatOnce: {
  756. break;
  757. }
  758. case MPPM_Shuffle:
  759. default : {
  760. m_PlayIndex = qrand() % getPathList(m_DiskType).size();
  761. break;
  762. }
  763. }
  764. q->playMusicIndex(m_DiskType, m_PlayIndex, 0);
  765. break;
  766. }
  767. default: {
  768. break;
  769. }
  770. }
  771. }
  772. void MusicPlayerPrivate::unsupportHandler()
  773. {
  774. Q_Q(MusicPlayer);
  775. m_EndTime = 0;
  776. QFileInfo fileInfo(m_CurrentFilePath);
  777. emit q->onMusicPlayerID3TagChange(m_DiskType,
  778. m_PlayIndex,
  779. fileInfo.filePath(),
  780. QString(),
  781. QString(),
  782. QString(),
  783. m_EndTime);
  784. m_ElapsedTime = 0;
  785. m_Millesimal = 0;
  786. emit q->onMusicPlayerElapsedInformation(m_ElapsedTime, m_Millesimal);
  787. setPlayStatus(MPPS_Unsupport);
  788. endOfFileHandler();
  789. }
  790. void MusicPlayerPrivate::exitMusicPlayer()
  791. {
  792. if (m_IsRunning) {
  793. quitMpalyer();
  794. setPlayStatus(MPPS_Exit);
  795. }
  796. }
  797. void MusicPlayerPrivate::createUSBFileNamesXml()
  798. {
  799. QDomDocument domDocument;
  800. domDocument.clear();
  801. domDocument.appendChild(domDocument.createElement(QString("MusicPlayer")));
  802. QDomElement root = domDocument.firstChildElement(QString("MusicPlayer"));
  803. QDomElement fileNames;
  804. QDomElement info;
  805. fileNames = domDocument.createElement(QString("USBFileNames"));
  806. root.appendChild(fileNames);
  807. m_USBFileNamesXml.clear();
  808. string pathInfo;
  809. LoadConfigString(pathInfo,USBMusicPathInfo);
  810. QString usbPersistantPathInfo = QString::fromStdString(pathInfo);
  811. QStringList stringList = usbPersistantPathInfo.split(QChar('/'));
  812. QString usbPersistantPath = usbPersistantPathInfo.left(usbPersistantPathInfo.length() - stringList.last().length() - 1);
  813. QString persistantIndex("");
  814. QFileInfo fileInfo;
  815. int i;
  816. for (i = 0; i < m_USBPathList.size(); ++i) {
  817. info = domDocument.createElement(QString("Index:" + QString::number(i)));
  818. fileNames.appendChild(info);
  819. m_MusicInformation.parserFilePath(m_USBPathList.at(i));
  820. m_USBFileArtistList.append(m_MusicInformation.getArtist());
  821. fileInfo.setFile(m_USBPathList.at(i));
  822. info.appendChild(domDocument.createTextNode(fileInfo.filePath()));
  823. if (persistantIndex.isEmpty()) {
  824. if (fileInfo.filePath() == usbPersistantPath) {
  825. if (usbPersistantPathInfo == (fileInfo.filePath() + QString("/") + fileInfo.created().toString(QString("yyyyMMddhhmmss")) + fileInfo.lastModified().toString(QString("yyyyMMddhhmmss")) + QString::number(fileInfo.size()))) {
  826. persistantIndex = QString::number(i);
  827. }
  828. }
  829. }
  830. }
  831. QDomElement persistant = domDocument.createElement(QString("USBPersistant"));
  832. root.appendChild(persistant);
  833. int mediaType = 0;
  834. LoadConfigString(mediaType,USBMultimedia);
  835. unsigned char multimediaType = (unsigned char)mediaType;
  836. int musicMillesmial = 0;
  837. if (persistantIndex.isEmpty()) {
  838. if (0 == i) {
  839. persistantIndex = QString("-1");
  840. multimediaType = MT_Idle;
  841. int value = MT_Image;
  842. SaveConfigString(value,USBMultimedia);
  843. system("sync");
  844. } else {
  845. if (0 == multimediaType) {
  846. multimediaType = MT_Music;
  847. SaveConfigString(multimediaType,USBMultimedia);
  848. system("sync");
  849. }
  850. persistantIndex = QString("0");
  851. }
  852. } else {
  853. LoadConfigString(musicMillesmial,USBMusicMillesmial);
  854. }
  855. QString data = persistantIndex + QString("-") + QString::number(musicMillesmial);
  856. persistant.appendChild(domDocument.createTextNode(data));
  857. QDomElement type = domDocument.createElement(QString("USBType"));
  858. root.appendChild(type);
  859. type.appendChild(domDocument.createTextNode(QString::number(multimediaType)));
  860. m_USBFileNamesXml = domDocument.toString();
  861. }
  862. void MusicPlayerPrivate::createSDFileNamesXml()
  863. {
  864. QDomDocument domDocument;
  865. domDocument.clear();
  866. domDocument.appendChild(domDocument.createElement(QString("MusicPlayer")));
  867. QDomElement root = domDocument.firstChildElement(QString("MusicPlayer"));
  868. QDomElement fileNames;
  869. QDomElement info;
  870. fileNames = domDocument.createElement(QString("SDFileNames"));
  871. root.appendChild(fileNames);
  872. m_SDFileNamesXml.clear();
  873. string pathInfo;
  874. LoadConfigString(pathInfo,SDMusicPathInfo);
  875. QString sdPersistantPathInfo = QString::fromStdString(pathInfo);
  876. QStringList stringList = sdPersistantPathInfo.split(QChar('/'));
  877. QString sdPersistantPath = sdPersistantPathInfo.left(sdPersistantPathInfo.length() - stringList.last().length() - 1);
  878. QString persistantIndex("");
  879. QFileInfo fileInfo;
  880. int i;
  881. for (i = 0; i < m_SDPathList.size(); ++i) {
  882. info = domDocument.createElement(QString("Index:" + QString::number(i)));
  883. fileNames.appendChild(info);
  884. m_MusicInformation.parserFilePath(m_SDPathList.at(i));
  885. m_SdFileArtistList.append(m_MusicInformation.getArtist());
  886. fileInfo.setFile(m_SDPathList.at(i));
  887. info.appendChild(domDocument.createTextNode(fileInfo.filePath()));
  888. if (persistantIndex.isEmpty()) {
  889. if (fileInfo.filePath() == sdPersistantPath) {
  890. if (sdPersistantPathInfo == (fileInfo.filePath() + QString("/") + fileInfo.created().toString(QString("yyyyMMddhhmmss")) + fileInfo.lastModified().toString(QString("yyyyMMddhhmmss")) + QString::number(fileInfo.size()))) {
  891. persistantIndex = QString::number(i);
  892. }
  893. }
  894. }
  895. }
  896. QDomElement persistant = domDocument.createElement(QString("SDPersistant"));
  897. root.appendChild(persistant);
  898. int mediaType = 0;
  899. LoadConfigString(mediaType,SDMultimedia);
  900. unsigned char multimediaType = (unsigned char)mediaType;
  901. int musicMillesmial = 0;
  902. if (persistantIndex.isEmpty()) {
  903. if (0 == i) {
  904. persistantIndex = QString("-1");
  905. multimediaType = MT_Idle;
  906. int value = MT_Image;
  907. SaveConfigString(value,SDMultimedia);
  908. system("sync");
  909. }else{
  910. if (0 == multimediaType) {
  911. multimediaType = MT_Music;
  912. SaveConfigString(multimediaType,SDMultimedia);
  913. system("sync");
  914. }
  915. persistantIndex = QString("0");
  916. }
  917. } else {
  918. LoadConfigString(musicMillesmial,SDMusicMillesmial);
  919. }
  920. QString data = persistantIndex + QString("-") + QString::number(musicMillesmial);
  921. persistant.appendChild(domDocument.createTextNode(data));
  922. QDomElement type = domDocument.createElement(QString("SDType"));
  923. root.appendChild(type);
  924. type.appendChild(domDocument.createTextNode(QString::number(multimediaType)));
  925. m_SDFileNamesXml = domDocument.toString();
  926. }
  927. void MusicPlayerPrivate::musicPlayerSetPlay()
  928. {
  929. switch (m_PlayStatus) {
  930. case MPPS_Pause: {
  931. char* cmd = "pause\n";
  932. writeCmdToMplayer(cmd);//暂停后播放
  933. break;
  934. }
  935. default: {
  936. break;
  937. }
  938. }
  939. }
  940. void MusicPlayerPrivate::musicPlayerSetPause()
  941. {
  942. switch (m_PlayStatus) {
  943. case MPPS_Start:
  944. case MPPS_Play: {
  945. char* cmd = "pause\n";
  946. writeCmdToMplayer(cmd);//暂停
  947. }
  948. case MPPS_Pause: {
  949. break;
  950. }
  951. default: {
  952. return ;
  953. break;
  954. }
  955. }
  956. }
  957. void MusicPlayerPrivate::musicPlayerSetStop()
  958. {
  959. if ((MPPS_Play == m_PlayStatus)
  960. || (MPPS_Pause == m_PlayStatus)) {
  961. char* cmd = "stop\n";
  962. writeCmdToMplayer(cmd);//停止播放
  963. } else {
  964. stopHandler();
  965. }
  966. }
  967. void MusicPlayerPrivate::musicPlayerSetExit(const DeviceWatcherType type)
  968. {
  969. if (type == m_DiskType) {
  970. exitMusicPlayer();
  971. }
  972. }
  973. void MusicPlayerPrivate::musicPlayerPlayStatus(int type,int status){
  974. Q_Q(MusicPlayer);
  975. emit q->onMusicPlayerPlayStatus(type, status);
  976. }
  977. void MusicPlayerPrivate::writeCmdToMplayer(char* cmd)
  978. {
  979. Q_Q(MusicPlayer);
  980. printf("+++[MusicPlayerPrivate::writeCmdToMplayer:%s]+++\n",cmd);
  981. if(m_Fd_w < 0)
  982. {
  983. m_Fd_w = open("/data/pipe",O_WRONLY | O_NONBLOCK | O_TRUNC);
  984. if(m_Fd_w < 0)
  985. {
  986. qDebug()<<"+++[MusicPlayerPrivate::writeCmdToMplayer:]+++";
  987. perror("open fifo error\n");
  988. m_ReadpThread = 0;
  989. return;
  990. }
  991. }
  992. ftruncate(m_Fd_w,0);
  993. lseek(m_Fd_w,0,SEEK_SET);
  994. write(m_Fd_w,cmd,strlen(cmd));
  995. }
  996. //退出mplayer
  997. void MusicPlayerPrivate::quitMpalyer(){
  998. Q_Q(MusicPlayer);
  999. qDebug()<<"+++[MusicPlayerPrivate::quitMpalyer()]+++";
  1000. char* cmd = "quit\n";
  1001. writeCmdToMplayer(cmd);
  1002. m_ReadpThread = 0;
  1003. usleep(500*1000);//等待线程退出
  1004. emit q->onMusicPlayerExit();
  1005. }
  1006. QString MusicPlayerPrivate::chgform(QString name) //歌名有空格的在空格前加/ (其实加上双引号“”就行)
  1007. {
  1008. qDebug()<<"+++[MusicPlayerPrivate::chgform]+++"<< name;
  1009. QString leftStr;
  1010. QString str;
  1011. str.clear();
  1012. while(name.size())
  1013. {
  1014. leftStr= name.left(1);
  1015. if(name.size()>1)
  1016. {
  1017. name = name.right(name.size()-1);
  1018. }
  1019. else{
  1020. name.clear();
  1021. }
  1022. if(leftStr == " ")
  1023. {
  1024. leftStr = "\\ ";
  1025. }
  1026. str += leftStr;
  1027. }
  1028. return str;
  1029. // char buf[512] = {0};
  1030. // qDebug()<<"++1111++";
  1031. // char *p = strtok(name, " ");
  1032. // printf( "%s\n", p );
  1033. // if(p != NULL){
  1034. // strcat(buf, p);
  1035. // strcat(buf, "\\ ");
  1036. // }
  1037. // p = strtok(NULL, " ");
  1038. // while(p != NULL)
  1039. // {
  1040. // if(strcmp(p,"\0")){
  1041. // strcat(buf, "\\ ");
  1042. // }
  1043. // else{
  1044. // strcat(buf, p);
  1045. // strcat(buf, "\\ ");
  1046. // }
  1047. // p = strtok(NULL, " ");
  1048. // }
  1049. }
  1050. ssize_t MusicPlayerPrivate::readLine(int fd, char *buffer, size_t n)
  1051. {
  1052. ssize_t numRead;
  1053. size_t totRead;
  1054. char *buf;
  1055. char ch;
  1056. if (n <= 0 || buffer == NULL) {
  1057. errno = EINVAL;
  1058. return -1;
  1059. }
  1060. buf = buffer;
  1061. totRead = 0;
  1062. for (;;) {
  1063. int flags = fcntl(fd,F_GETFL,0);
  1064. flags |= O_NONBLOCK;
  1065. fcntl(fd,F_SETFL,flags);
  1066. numRead = read(fd, &ch, 1);
  1067. if (-1 == numRead) {
  1068. if (errno == EINTR) {
  1069. continue;
  1070. } else {
  1071. return -1;
  1072. }
  1073. } else if (numRead == 0) {
  1074. if (totRead == 0) {
  1075. return 0;
  1076. } else {
  1077. break;
  1078. }
  1079. } else {
  1080. if (totRead < n - 1) {
  1081. totRead++;
  1082. *buf++ = ch;
  1083. }
  1084. if (ch == '\n') {
  1085. break;
  1086. }
  1087. }
  1088. }
  1089. *buf = '\0';
  1090. return totRead;
  1091. }