Index: libs/libmythtv/remoteutil.h
===================================================================
--- libs/libmythtv/remoteutil.h	(revision 7092)
+++ libs/libmythtv/remoteutil.h	(working copy)
@@ -25,6 +25,7 @@
 bool RemoteGetUptime(time_t &uptime);
 bool RemoteGetMemStats(int &totalMB, int &freeMB, int &totalVM, int &freeVM);
 bool RemoteCheckFile(ProgramInfo *pginfo);
+bool RemoteIsPlaying(const ProgramInfo *pginfo);
 void RemoteStopRecording(ProgramInfo *pginfo);
 bool RemoteDeleteRecording(ProgramInfo *pginfo, bool forgetHistory,
                            bool forceMetadataDelete = false);
Index: libs/libmythtv/remoteutil.cpp
===================================================================
--- libs/libmythtv/remoteutil.cpp	(revision 7092)
+++ libs/libmythtv/remoteutil.cpp	(working copy)
@@ -130,6 +130,17 @@
     return strlist[0].toInt();
 }
 
+bool RemoteIsPlaying(const ProgramInfo *pginfo)
+{
+    QStringList strlist = "QUERY_IS_PLAYING";
+    pginfo->ToStringList(strlist);
+
+    if (!gContext->SendReceiveStringList(strlist))
+        return false;
+
+    return strlist[0].toInt();    
+}
+
 void RemoteStopRecording(ProgramInfo *pginfo)
 {
     QStringList strlist = QString("STOP_RECORDING");
Index: libs/libmythtv/tv_rec.cpp
===================================================================
--- libs/libmythtv/tv_rec.cpp	(revision 7092)
+++ libs/libmythtv/tv_rec.cpp	(working copy)
@@ -289,6 +289,18 @@
     return internalState;
 }
 
+/** \fn TVRec::IsPlaying(const ProgramInfo*)
+ *  \brief Returns true iff we are playing the program indicated.
+ *  \param pginfo Program we want to compare to curRecording
+ */
+bool TVRec::IsPlaying(const ProgramInfo *pginfo)
+{
+    QMutexLocker lock(&stateChangeLock);
+    if (curRecording && pginfo && StateIsPlaying(GetState()))
+        return (curRecording->IsSameProgram(*pginfo));
+    return false;
+}
+
 /** \fn TVRec::GetRecording(void)
  *  \brief Allocates and returns a ProgramInfo for the current recording.
  *
Index: libs/libmythtv/tv_rec.h
===================================================================
--- libs/libmythtv/tv_rec.h	(revision 7092)
+++ libs/libmythtv/tv_rec.h	(working copy)
@@ -67,6 +67,7 @@
 
     bool Init(void);
 
+    bool IsPlaying(const ProgramInfo *pginfo);
     void RecordPending(const ProgramInfo *rcinfo, int secsleft);
     int StartRecording(const ProgramInfo *rcinfo);
 
Index: programs/mythbackend/encoderlink.h
===================================================================
--- programs/mythbackend/encoderlink.h	(revision 7092)
+++ programs/mythbackend/encoderlink.h	(working copy)
@@ -52,6 +52,7 @@
 
     TVState GetState();
     bool IsRecording(const ProgramInfo *rec); // scheduler call only.
+    bool IsPlaying(const ProgramInfo *rec);
 
     bool HasEnoughFreeSpace(const ProgramInfo *rec,
                             bool try_to_use_cache = false);
Index: programs/mythbackend/playbacksock.cpp
===================================================================
--- programs/mythbackend/playbacksock.cpp	(revision 7092)
+++ programs/mythbackend/playbacksock.cpp	(working copy)
@@ -228,6 +228,24 @@
     return ret;
 }
 
+/** \fn PlaybackSock::IsPlaying(int, const ProgramInfo*)
+ *  \brief Returns whether the particular program in pginfo is currently.
+ *         being viewed.
+ *  \param capturecardnum Recorder ID in the database.
+ */
+bool PlaybackSock::IsPlaying(int capturecardnum, const ProgramInfo *pginfo)
+{
+    QStringList strlist = QString("QUERY_REMOTEENCODER %1").arg(capturecardnum);
+    strlist << "IS_PLAYING";
+    pginfo->ToStringList(strlist);
+
+    SendReceiveStringList(strlist);
+
+    bool ret = strlist[0].toInt();
+    return ret;
+}
+
+
 int PlaybackSock::StartRecording(int capturecardnum, const ProgramInfo *pginfo)
 {
     QStringList strlist = QString("QUERY_REMOTEENCODER %1").arg(capturecardnum);
Index: programs/mythbackend/mainserver.cpp
===================================================================
--- programs/mythbackend/mainserver.cpp	(revision 7092)
+++ programs/mythbackend/mainserver.cpp	(working copy)
@@ -309,6 +309,10 @@
     {
         HandleQueryCheckFile(listline, pbs);
     }
+    else if (command == "QUERY_IS_PLAYING")
+    {
+        HandleQueryIsPlaying(listline, pbs);
+    }
     else if (command == "QUERY_GUIDEDATATHROUGH")
     {
         HandleQueryGuideDataThrough(pbs);
@@ -1904,6 +1908,29 @@
     delete pginfo;
 }
 
+void MainServer::HandleQueryIsPlaying(QStringList &slist, PlaybackSock *pbs)
+{
+    QSocket *pbssock = pbs->getSocket();
+
+    ProgramInfo *pginfo = new ProgramInfo();
+    pginfo->FromStringList(slist, 1);
+
+    int playing = 0;
+
+    if (!ismaster)
+        VERBOSE(VB_IMPORTANT, "HandleQueryIsPlaying called on non-master...");
+
+    // check each recorder to see if they are playing the stream.
+    QMap<int, EncoderLink *>::Iterator iter = encoderList->begin();
+    for (; iter != encoderList->end() && !playing; ++iter)
+        playing |= (iter.data())->IsPlaying(pginfo);
+
+    QStringList strlist = QString::number(playing);
+    SendResponse(pbssock, strlist);
+
+    delete pginfo;
+}
+
 void MainServer::getGuideDataThrough(QDateTime &GuideDataThrough)
 {
     MSqlQuery query(MSqlQuery::InitCon());
@@ -2715,6 +2742,15 @@
 
         delete pginfo;
     }
+    else if (command == "IS_PLAYING")
+    {
+        ProgramInfo *pginfo = new ProgramInfo();
+        pginfo->FromStringList(slist, 2);
+
+        retlist << QString::number((int)enc->IsPlaying(pginfo));
+
+        delete pginfo;
+    }
     else if (command == "START_RECORDING")
     {
         ProgramInfo *pginfo = new ProgramInfo();
Index: programs/mythbackend/playbacksock.h
===================================================================
--- programs/mythbackend/playbacksock.h	(revision 7092)
+++ programs/mythbackend/playbacksock.h	(working copy)
@@ -53,6 +53,7 @@
     int GetEncoderState(int capturecardnum);
     long long GetMaxBitrate(int capturecardnum);
     bool EncoderIsRecording(int capturecardnum, const ProgramInfo *pginfo);
+    bool IsPlaying(int capturecardnum, const ProgramInfo *pginfo);
     int StartRecording(int capturecardnum, const ProgramInfo *pginfo);
     void RecordPending(int capturecardnum, const ProgramInfo *pginfo, int secsleft);
     int SetSignalMonitoringRate(int capturecardnum, int rate, int notifyFrontend);
Index: programs/mythbackend/mainserver.h
===================================================================
--- programs/mythbackend/mainserver.h	(revision 7092)
+++ programs/mythbackend/mainserver.h	(working copy)
@@ -83,6 +83,7 @@
     void HandleRescheduleRecordings(int recordid, PlaybackSock *pbs);
     void HandleQueryFreeSpace(PlaybackSock *pbs, bool allBackends);
     void HandleQueryCheckFile(QStringList &slist, PlaybackSock *pbs);
+    void HandleQueryIsPlaying(QStringList &slist, PlaybackSock *pbs);
     void HandleQueryGuideDataThrough(PlaybackSock *pbs);
     void HandleGetPendingRecordings(PlaybackSock *pbs);
     void HandleGetScheduledRecordings(PlaybackSock *pbs);
Index: programs/mythbackend/autoexpire.cpp
===================================================================
--- programs/mythbackend/autoexpire.cpp	(revision 7092)
+++ programs/mythbackend/autoexpire.cpp	(working copy)
@@ -278,6 +278,7 @@
  *
  *   CheckFile makes sure the file exists and is stored on the same file
  *   system as the recordfileprefix.
+ *
  *  \param pginfo           ProgramInfo for the program we wish to delete.
  *  \param recordfileprefix Path where new recordings are stored.
  *  \param fsid             Unique ID of recordfileprefix's filesystem.
@@ -322,6 +323,15 @@
         VERBOSE(VB_FILE, msg);
         return false;
     }
+
+    // query recorders to see if the file is currently being played
+    if (RemoteIsPlaying(pginfo))
+    {
+        VERBOSE(VB_FILE, QString("File '%1' is currently being played. "
+                                 "Not autoexpiring").arg(filename));
+        return false;
+    }
+
     return true;
 }
 
Index: programs/mythbackend/encoderlink.cpp
===================================================================
--- programs/mythbackend/encoderlink.cpp	(revision 7092)
+++ programs/mythbackend/encoderlink.cpp	(working copy)
@@ -1,7 +1,3 @@
-// C++ headers
-#include <iostream>
-using namespace std;
-
 // C headers
 #include <unistd.h>
 
@@ -137,7 +133,9 @@
     else if (sock)
         retval = (TVState)sock->GetEncoderState(m_capturecardnum);
     else
-        cerr << "Broken for card: " << m_capturecardnum << endl;
+        VERBOSE(VB_IMPORTANT,
+                QString("EncoderLink::GetState() failed for recorder %1")
+                .arg(m_capturecardnum));
 
     return retval;
 }
@@ -145,7 +143,7 @@
 /** \fn EncoderLink::IsRecording(const ProgramInfo *rec)
  *  \brief Returns true if rec is scheduled for recording.
  *  \param rec Recording to check.
- *  \sa MatchesRecording(const ProgramInfo*)
+ *  \sa MatchesRecording(const ProgramInfo*), IsPlaying(const ProgramInfo *)
  */
 bool EncoderLink::IsRecording(const ProgramInfo *rec)
 {
@@ -157,6 +155,27 @@
     return retval;
 }
 
+/** \fn EncoderLink::IsPlaying(const ProgramInfo *)
+ *  \brief Returns true iff recording is currently being played.
+ *  \param rec Recording to check.
+ *  \sa IsRecording(const ProgramInfo*), MatchesRecording(const ProgramInfo*)
+ */
+bool EncoderLink::IsPlaying(const ProgramInfo *rec)
+{
+    bool retval = false;
+
+    if (local)
+        retval = tv->IsPlaying(rec);
+    else if (sock)
+        retval = sock->IsPlaying(m_capturecardnum, rec);
+    else
+        VERBOSE(VB_IMPORTANT,
+                QString("EncoderLink::IsPlaying() failed for recorder %1")
+                .arg(m_capturecardnum));
+
+    return retval;
+}
+
 /** \fn EncoderLink::MatchesRecording(const ProgramInfo *rec)
  *  \brief Returns true if rec is actually being recorded by TVRec.
  *  
@@ -190,11 +209,11 @@
             delete tvrec;
         }
     }
+    else if (sock)
+        retval = sock->EncoderIsRecording(m_capturecardnum, rec);
     else
-    {
-        if (sock)
-            retval = sock->EncoderIsRecording(m_capturecardnum, rec);
-    }
+        VERBOSE(VB_IMPORTANT, QString("EncoderLink::MatchesRecording() "
+                    "failed for recorder %1").arg(m_capturecardnum));
 
     return retval;
 }
