Switch to unified view

a/src/ohsndrcv.cxx b/src/ohsndrcv.cxx
...
...
44
    }
44
    }
45
    void clear() {
45
    void clear() {
46
        if (dev && origmpd) {
46
        if (dev && origmpd) {
47
            dev->m_mpdcli = origmpd;
47
            dev->m_mpdcli = origmpd;
48
            origmpd = 0;
48
            origmpd = 0;
49
            if (dev->m_ohpl) {
50
                dev->m_ohpl->resetQVers();
51
            }
52
            if (dev->m_ohrcv) {
49
            if (dev->m_ohrcv) {
53
                dev->m_ohrcv->iStop();
50
                dev->m_ohrcv->iStop();
51
            }
52
            if (dev->m_ohpl) {
53
                dev->m_ohpl->refreshState();
54
            }
54
            }
55
        }
55
        }
56
        delete mpd;
56
        delete mpd;
57
        delete cmd;
57
        delete cmd;
58
    }
58
    }
59
    UpMpd *dev;
59
    UpMpd *dev;
60
    MPDCli *mpd;
60
    MPDCli *mpd;
61
    MPDCli *origmpd;
61
    MPDCli *origmpd;
62
    ExecCmd *cmd;
62
    ExecCmd *cmd;
63
    string uri;
64
    string meta;
63
};
65
};
64
66
65
67
66
SenderReceiver::SenderReceiver(UpMpd *dev)
68
SenderReceiver::SenderReceiver(UpMpd *dev)
67
{
69
{
...
...
72
{
74
{
73
    if (m)
75
    if (m)
74
        delete m;
76
        delete m;
75
}
77
}
76
78
79
static bool copyMpd(MPDCli *src, MPDCli *dest, int seekms)
80
{
81
    if (!src || !dest) {
82
        LOGERR("copyMpd: src or dest is null\n");
83
        return false;
84
    }
85
86
    // Playing state. If playing is stopped at this point elapsedms is
87
    // lost which is why we get it as a parameter
88
    MpdStatus mpds = src->getStatus();
89
    if (seekms < 0) {
90
        seekms = mpds.songelapsedms;
91
    }
92
    // Playlist from source mpd
93
    vector<UpSong> playlist;
94
    if (!src->getQueueData(playlist)) {
95
        LOGERR("copyMpd: can't retrieve current playlist\n");
96
        return false;
97
    }
98
    // Copy the playlist to dest
99
    dest->clearQueue();
100
    for (unsigned int i = 0; i < playlist.size(); i++) {
101
        if (dest->insert(playlist[i].uri, i, playlist[i]) < 0) {
102
            LOGERR("copyMpdt: mpd->insert failed\n");
103
            return false;
104
        }
105
    }
106
    dest->play(mpds.songpos);
107
    dest->setVolume(mpds.volume);
108
    dest->seek(seekms/1000);
109
    return true;
110
}
111
77
bool SenderReceiver::start(int seekms)
112
bool SenderReceiver::start(int seekms)
78
{
113
{
79
    LOGDEB("SenderReceiver::start. seekms " << seekms << endl);
114
    LOGDEB("SenderReceiver::start. seekms " << seekms << endl);
80
    
115
    
81
    if (!m->dev || !m->dev->m_ohpl) {
116
    if (!m->dev || !m->dev->m_ohpl) {
82
        LOGERR("SenderReceiver::start: no ohpl\n");
117
        LOGERR("SenderReceiver::start: no ohpl\n");
83
        return false;
118
        return false;
84
    }
119
    }
85
    
120
    
86
    // Playing state. Playing is stopped at this point (source switch), so
87
    // we get the elapsedms (would be 0) as input param.
88
    MpdStatus mpds = m->dev->getMpdStatusNoUpdate();
89
90
    // Retrieve the current playlist from the normal MPD
91
    vector<UpSong> playlist;
92
    if (!m->dev->m_mpdcli || !m->dev->m_mpdcli->getQueueData(playlist)) {
93
        LOGERR("SenderReceiver::start: can't retrieve current playlist\n");
94
        return false;
95
    }
96
97
    // Stop MPD Play (normally already done)
121
    // Stop MPD Play (normally already done)
98
    m->dev->m_mpdcli->stop();
122
    m->dev->m_mpdcli->stop();
99
123
124
    if (!m->cmd) {
100
    // Start fifo MPD and Sender
125
        // First time: Start fifo MPD and Sender
101
    m->cmd = new ExecCmd();
126
        m->cmd = new ExecCmd();
102
    vector<string> args;
127
        vector<string> args;
103
    args.push_back("-p");
128
        args.push_back("-p");
104
    args.push_back(SoapHelp::i2s(mpdport));
129
        args.push_back(SoapHelp::i2s(mpdport));
130
        args.push_back("-f");
131
        args.push_back(m->dev->m_friendlyname);
105
    m->cmd->startExec(makesendercmd, args, false, true);
132
        m->cmd->startExec(makesendercmd, args, false, true);
106
133
107
    string output;
134
        string output;
108
    if (!m->cmd->getline(output)) {
135
        if (!m->cmd->getline(output)) {
109
        LOGERR("SenderReceiver::start: makesender command failed\n");
136
            LOGERR("SenderReceiver::start: makesender command failed\n");
110
        m->clear();
137
            m->clear();
111
        return false;
138
            return false;
112
    }
139
        }
113
    LOGDEB("SenderReceiver::start got [" << output << "] from script\n");
140
        LOGDEB("SenderReceiver::start got [" << output << "] from script\n");
114
141
115
    // Output is like [Ok mpdport URI base64-encoded-uri METADATA b64-meta]
142
        // Output is like [Ok mpdport URI base64-encoded-uri METADATA b64-meta]
116
    vector<string> toks;
143
        vector<string> toks;
117
    stringToTokens(output, toks);
144
        stringToTokens(output, toks);
118
    if (toks.size() != 6 || toks[0].compare("Ok")) {
145
        if (toks.size() != 6 || toks[0].compare("Ok")) {
119
        LOGERR("SenderReceiver::start: bad output from script: " << output
146
            LOGERR("SenderReceiver::start: bad output from script: " << output
120
               << endl);
147
                   << endl);
121
        m->clear();
148
            m->clear();
122
        return false;
149
            return false;
123
    }
150
        }
124
    string uri = base64_decode(toks[3]);
151
        m->uri = base64_decode(toks[3]);
125
    string meta = base64_decode(toks[5]);
152
        m->meta = base64_decode(toks[5]);
126
    
153
127
    // Connect to the new MPD, and copy the playlist
154
        // Connect to the new MPD
128
    m->mpd = new MPDCli("localhost", mpdport);
155
        m->mpd = new MPDCli("localhost", mpdport);
129
    if (!m->mpd || !m->mpd->ok()) {
156
        if (!m->mpd || !m->mpd->ok()) {
130
        LOGERR("SenderReceiver::start: can't connect to new MPD\n");
157
            LOGERR("SenderReceiver::start: can't connect to new MPD\n");
131
        m->clear();
132
        return false;
133
    }
134
    for (unsigned int i = 0; i < playlist.size(); i++) {
135
        if (m->mpd->insert(playlist[i].uri, i, playlist[i]) < 0) {
136
            LOGERR("SenderReceiver::start: mpd->insert failed\n");
137
            m->clear();
158
            m->clear();
138
            return false;
159
            return false;
139
        }
160
        }
140
    }
161
    }
141
    
162
    
142
    // Start our receiver
163
    // Start our receiver
143
    if (!m->dev->m_ohrcv->iSetSender(uri, meta) ||
164
    if (!m->dev->m_ohrcv->iSetSender(m->uri, m->meta) ||
144
        !m->dev->m_ohrcv->iPlay()) {
165
        !m->dev->m_ohrcv->iPlay()) {
145
        m->clear();
166
        m->clear();
146
        return false;
167
        return false;
147
    }
168
    }
148
169
149
    // Replace the original mpd and play
170
    // Copy mpd state 
171
    copyMpd(m->dev->m_mpdcli, m->mpd, seekms);
150
    m->origmpd = m->dev->m_mpdcli;
172
    m->origmpd = m->dev->m_mpdcli;
151
    m->dev->m_mpdcli = m->mpd;
173
    m->dev->m_mpdcli = m->mpd;
152
    LOGDEB("SenderReceiver::starting new mpd. songelapsedms: " <<
174
153
           mpds.songelapsedms << endl);
154
    m->mpd->setVolume(mpds.volume);
155
    m->mpd->play(mpds.songpos);
156
    m->mpd->seek(seekms/1000);
157
    m->mpd->setVolume(mpds.volume);
158
    return true;
175
    return true;
159
}
176
}
160
177
161
bool SenderReceiver::stop()
178
bool SenderReceiver::stop()
162
{
179
{
163
    LOGDEB("SenderReceiver::stop()\n");
180
    LOGDEB("SenderReceiver::stop()\n");
164
    // Do we want to transfer the playlist back ? Probably we do.
181
    // Do we want to transfer the playlist back ? Probably we do.
165
    m->clear();
182
    if (!m->dev || !m->origmpd || !m->mpd || !m->dev->m_ohpl ||
183
        !m->dev->m_ohrcv) {
184
        LOGERR("SenderReceiver::stop: bad state: dev/origmpd/mpd null\n");
185
        return false;
186
    }
187
    copyMpd(m->mpd, m->origmpd, -1);
188
    m->mpd->stop();
189
    m->dev->m_mpdcli = m->origmpd;
190
    m->origmpd = 0;
191
    m->dev->m_ohrcv->iStop();
192
    m->dev->m_ohpl->refreshState();
193
166
    return true;
194
    return true;
167
}
195
}