static int QueueJob(const MythUtilCommandLineParser &cmdline) { ProgramInfo pginfo; if (!GetProgramInfo(cmdline, pginfo)) return GENERIC_EXIT_NO_RECORDING_DATA; bool rebuildSeektable = false; int jobType = JOB_NONE; if (cmdline.toString("queuejob") == "transcode") jobType = JOB_TRANSCODE; else if (cmdline.toString("queuejob") == "commflag") jobType = JOB_COMMFLAG; else if (cmdline.toString("queuejob") == "rebuild") { jobType = JOB_COMMFLAG; rebuildSeektable = true; } else if (cmdline.toString("queuejob") == "metadata") jobType = JOB_METADATA; else if (cmdline.toString("queuejob") == "userjob1") jobType = JOB_USERJOB1; else if (cmdline.toString("queuejob") == "userjob2") jobType = JOB_USERJOB1; else if (cmdline.toString("queuejob") == "userjob4") jobType = JOB_USERJOB1; else if (cmdline.toString("queuejob") == "userjob4") jobType = JOB_USERJOB1; else if (cmdline.toInt("queuejob") > 0) jobType = cmdline.toInt("queuejob"); if (jobType == JOB_NONE) { LOG(VB_GENERAL, LOG_ERR, "Error, invalid job type given with queuejob option"); return GENERIC_EXIT_INVALID_CMDLINE; } bool result = JobQueue::QueueJob(jobType, pginfo.GetChanID(), pginfo.GetRecordingStartTime(), "", "", "", rebuildSeektable, JOB_QUEUED, QDateTime()); if (result) { QString tmp = QString("%1 Job Queued for chanid %2 @ %3") .arg(cmdline.toString("queuejob")) .arg(pginfo.GetChanID()) .arg(pginfo.GetRecordingStartTime().toString()); cerr << tmp.toLocal8Bit().constData() << endl; return GENERIC_EXIT_OK; } QString tmp = QString("Error queueing job for chanid %1 @ %2") .arg(pginfo.GetChanID()) .arg(pginfo.GetRecordingStartTime().toString()); cerr << tmp.toLocal8Bit().constData() << endl; return GENERIC_EXIT_DB_ERROR; }
static int SendMessage(const MythUtilCommandLineParser &cmdline) { QHostAddress address = QHostAddress::Broadcast; unsigned short port = 6948; QString message = kMessage; if (cmdline.toBool("udpport")) port = (unsigned short)cmdline.toUInt("udpport"); if (cmdline.toBool("bcastaddr")) address.setAddress(cmdline.toString("bcastaddr")); QMap<QString,QString>::const_iterator i; QMap<QString,QString> extras = cmdline.GetExtra(); for (i = extras.begin(); i != extras.end(); ++i) { QString name = i.key(); QString value = i.value(); name.replace("--", ""); cerr << "name: " << name.toLocal8Bit().constData() << " -- value: " << value.toLocal8Bit().constData() << endl; name.append("%"); name.prepend("%"); message.replace(name, value); } cout << "output:\n" << message.toLocal8Bit().constData() << endl; QUdpSocket *sock = new QUdpSocket(); QByteArray utf8 = message.toUtf8(); int result = GENERIC_EXIT_OK; if (sock->writeDatagram(utf8, address, port) < 0) { cout << "Failed to send UDP/XML packet" << endl; result = GENERIC_EXIT_NOT_OK; } else { cout << "Sent UDP/XML packet to IP " << address.toString().toLocal8Bit().constData() << " and port: " << port << endl; } sock->deleteLater(); return result; }
static int ParseVideoFilename(const MythUtilCommandLineParser &cmdline) { QString filename = cmdline.toString("parsevideo"); cout << "Title: " << VideoMetadata::FilenameToMeta(filename, 1) .toLocal8Bit().constData() << endl << "Season: " << VideoMetadata::FilenameToMeta(filename, 2) .toLocal8Bit().constData() << endl << "Episode: " << VideoMetadata::FilenameToMeta(filename, 3) .toLocal8Bit().constData() << endl << "Subtitle: " << VideoMetadata::FilenameToMeta(filename, 4) .toLocal8Bit().constData() << endl; return GENERIC_EXIT_OK; }
bool GetProgramInfo(const MythUtilCommandLineParser &cmdline, ProgramInfo &pginfo) { if (cmdline.toBool("video")) { QString video = cmdline.toString("video"); pginfo = ProgramInfo(video); return true; } if (!cmdline.toBool("chanid")) { LOG(VB_GENERAL, LOG_ERR, "No chanid specified"); return false; } if (!cmdline.toBool("starttime")) { LOG(VB_GENERAL, LOG_ERR, "No start time specified"); return false; } uint chanid = cmdline.toUInt("chanid"); QDateTime starttime = cmdline.toDateTime("starttime"); QString startstring = starttime.toString("yyyyMMddhhmmss"); const ProgramInfo tmpInfo(chanid, starttime); if (!tmpInfo.GetChanID()) { LOG(VB_GENERAL, LOG_ERR, QString("No program data exists for channel %1 at %2") .arg(chanid).arg(startstring)); return false; } pginfo = tmpInfo; return true; }
static int SetSkipList(const MythUtilCommandLineParser &cmdline) { return SetMarkupList(cmdline, QString("skiplist"), cmdline.toString("setskiplist")); }
static int SendSystemEvent(const MythUtilCommandLineParser &cmdline) { return RawSendEvent(QStringList(QString("SYSTEM_EVENT %1 SENDER %2") .arg(cmdline.toString("systemevent")) .arg(gCoreContext->GetHostName()))); }
static int ExtractImage(const MythUtilCommandLineParser &cmdline) { if (cmdline.toString("songid").isEmpty()) { LOG(VB_GENERAL, LOG_ERR, "Missing --songid option"); return GENERIC_EXIT_INVALID_CMDLINE; } if (cmdline.toString("imagetype").isEmpty()) { LOG(VB_GENERAL, LOG_ERR, "Missing --imagetype option"); return GENERIC_EXIT_INVALID_CMDLINE; } int songID = cmdline.toInt("songid"); ImageType type = (ImageType)cmdline.toInt("imagetype"); MusicMetadata *mdata = MusicMetadata::createFromID(songID); if (!mdata) { LOG(VB_GENERAL, LOG_ERR, QString("Cannot find metadata for trackid: %1").arg(songID)); return GENERIC_EXIT_NOT_OK; } AlbumArtImage *image = mdata->getAlbumArtImages()->getImage(type); if (!image) { LOG(VB_GENERAL, LOG_ERR, QString("Cannot find image of type: %1").arg(type)); return GENERIC_EXIT_NOT_OK; } MetaIO *tagger = mdata->getTagger(); if (!tagger) { LOG(VB_GENERAL, LOG_ERR, QString("Cannot find a tagger for this file: %1").arg(mdata->Filename(false))); return GENERIC_EXIT_NOT_OK; } if (!image->embedded || !tagger->supportsEmbeddedImages()) { LOG(VB_GENERAL, LOG_ERR, QString("Either the image isn't embedded or the tagger doesn't support embedded images")); return GENERIC_EXIT_NOT_OK; } // find the tracks actual filename StorageGroup musicGroup("Music", gCoreContext->GetHostName(), false); QString trackFilename = musicGroup.FindFile(mdata->Filename(false)); // where are we going to save the image QString path; StorageGroup artGroup("MusicArt", gCoreContext->GetHostName(), false); QStringList dirList = artGroup.GetDirList(); if (dirList.size()) path = artGroup.FindNextDirMostFree(); if (!QDir(path).exists()) { LOG(VB_GENERAL, LOG_ERR, "Cannot find a directory in the 'MusicArt' storage group to save to"); return GENERIC_EXIT_NOT_OK; } path += "/AlbumArt/"; QDir dir(path); QString filename = QString("%1-%2.jpg").arg(mdata->ID()).arg(AlbumArtImages::getTypeFilename(image->imageType)); if (QFile::exists(path + filename)) QFile::remove(path + filename); if (!dir.exists()) dir.mkpath(path); QImage *saveImage = tagger->getAlbumArt(trackFilename, image->imageType); if (saveImage) { saveImage->save(path + filename, "JPEG"); delete saveImage; } delete tagger; // tell any clients that the albumart for this track has changed gCoreContext->SendMessage(QString("MUSIC_ALBUMART_CHANGED %1 %2").arg(songID).arg(type)); return GENERIC_EXIT_OK; }
static int UpdateMeta(const MythUtilCommandLineParser &cmdline) { bool ok = true; int result = GENERIC_EXIT_OK; if (cmdline.toString("songid").isEmpty()) { LOG(VB_GENERAL, LOG_ERR, "Missing --songid option"); return GENERIC_EXIT_INVALID_CMDLINE; } int songID = cmdline.toInt("songid"); MusicMetadata *mdata = MusicMetadata::createFromID(songID); if (!mdata) { LOG(VB_GENERAL, LOG_ERR, QString("Cannot find metadata for trackid: %1").arg(songID)); return GENERIC_EXIT_NOT_OK; } if (!cmdline.toString("title").isEmpty()) mdata->setTitle(cmdline.toString("title")); if (!cmdline.toString("artist").isEmpty()) mdata->setArtist(cmdline.toString("artist")); if (!cmdline.toString("album").isEmpty()) mdata->setAlbum(cmdline.toString("album")); if (!cmdline.toString("genre").isEmpty()) mdata->setGenre(cmdline.toString("genre")); if (!cmdline.toString("trackno").isEmpty()) mdata->setTrack(cmdline.toInt("trackno")); if (!cmdline.toString("year").isEmpty()) mdata->setYear(cmdline.toInt("year")); if (!cmdline.toString("rating").isEmpty()) mdata->setRating(cmdline.toInt("rating")); if (!cmdline.toString("playcount").isEmpty()) mdata->setPlaycount(cmdline.toInt("playcount")); if (!cmdline.toString("lastplayed").isEmpty()) mdata->setLastPlay(cmdline.toDateTime("lastplayed")); mdata->dumpToDatabase(); MetaIO *tagger = mdata->getTagger(); if (tagger) { ok = tagger->write(mdata->getLocalFilename(), mdata); if (!ok) LOG(VB_GENERAL, LOG_ERR, QString("Failed to write to tag for trackid: %1").arg(songID)); } // tell any clients that the metadata for this track has changed gCoreContext->SendMessage(QString("MUSIC_METADATA_CHANGED %1").arg(songID)); if (!ok) result = GENERIC_EXIT_NOT_OK; return result; }
static int CalcTrackLength(const MythUtilCommandLineParser &cmdline) { if (cmdline.toString("songid").isEmpty()) { LOG(VB_GENERAL, LOG_ERR, "Missing --songid option"); return GENERIC_EXIT_INVALID_CMDLINE; } int songID = cmdline.toInt("songid"); MusicMetadata *mdata = MusicMetadata::createFromID(songID); if (!mdata) { LOG(VB_GENERAL, LOG_ERR, QString("Cannot find metadata for trackid: %1").arg(songID)); return GENERIC_EXIT_NOT_OK; } QString musicFile = mdata->getLocalFilename(); if (musicFile.isEmpty() || !QFile::exists(musicFile)) { LOG(VB_GENERAL, LOG_ERR, QString("Cannot find file for trackid: %1").arg(songID)); return GENERIC_EXIT_NOT_OK; } av_register_all(); AVFormatContext *inputFC = NULL; AVInputFormat *fmt = NULL; // Open track LOG(VB_GENERAL, LOG_DEBUG, QString("CalcTrackLength: Opening '%1'") .arg(musicFile)); QByteArray inFileBA = musicFile.toLocal8Bit(); int ret = avformat_open_input(&inputFC, inFileBA.constData(), fmt, NULL); if (ret) { LOG(VB_GENERAL, LOG_ERR, "CalcTrackLength: Couldn't open input file" + ENO); return GENERIC_EXIT_NOT_OK; } // Getting stream information ret = avformat_find_stream_info(inputFC, NULL); if (ret < 0) { LOG(VB_GENERAL, LOG_ERR, QString("CalcTrackLength: Couldn't get stream info, error #%1").arg(ret)); avformat_close_input(&inputFC); inputFC = NULL; return GENERIC_EXIT_NOT_OK;; } int duration = 0; long long time = 0; for (uint i = 0; i < inputFC->nb_streams; i++) { AVStream *st = inputFC->streams[i]; char buf[256]; avcodec_string(buf, sizeof(buf), st->codec, false); switch (inputFC->streams[i]->codec->codec_type) { case AVMEDIA_TYPE_AUDIO: { AVPacket pkt; av_init_packet(&pkt); while (av_read_frame(inputFC, &pkt) >= 0) { if (pkt.stream_index == (int)i) time = time + pkt.duration; av_free_packet(&pkt); } duration = time * av_q2d(inputFC->streams[i]->time_base); break; } default: LOG(VB_GENERAL, LOG_ERR, QString("Skipping unsupported codec %1 on stream %2") .arg(inputFC->streams[i]->codec->codec_type).arg(i)); break; } } // Close input file avformat_close_input(&inputFC); inputFC = NULL; if (mdata->Length() / 1000 != duration) { LOG(VB_GENERAL, LOG_INFO, QString("The length of this track in the database was %1s " "it is now %2s").arg(mdata->Length() / 1000).arg(duration)); // update the track length in the database mdata->setLength(duration * 1000); mdata->dumpToDatabase(); // tell any clients that the metadata for this track has changed gCoreContext->SendMessage(QString("MUSIC_METADATA_CHANGED %1").arg(songID)); } else { LOG(VB_GENERAL, LOG_INFO, QString("The length of this track is unchanged %1s") .arg(mdata->Length() / 1000)); } return GENERIC_EXIT_OK; }