问:
Android ShoutCast Internet Radio FilenotFoundException
I developed Shoutcastinternet Radio Streaming(Stream URL:http://123.176.41.8:8256) in Andriod and i'm able to stream and play Successfully.

But the problem is: when i execute my application,I'm able to stream and play Continuously for someextend(20min,halfanhour etc...),

after that the stream is getting stoped(I'm not ableto play the stream),Could any one help?

I logged the Error,after Stream get Stopped.

```<code>The Error is:
D/dalvikvm(1238): GC_FOR_MALLOC freed 51742 objects / 1928072 bytes in 80ms(I'm repeating this statement in the log file while running my application on real Device)
</code>```

Update:

 Exception:

```<code>  04-27 18:31:05.753: V/MediaPlayer(26201): start
04-27 18:31:05.753: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.753: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.753: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.753: E/MediaPlayer(26201): callback application
04-27 18:31:05.753: E/MediaPlayer(26201): back from callback
04-27 18:31:05.753: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.753: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.757: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.757: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.757: V/MediaPlayer(26201): reset
04-27 18:31:05.757: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.757: V/MediaPlayer(26201): start
04-27 18:31:05.757: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.757: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.757: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.757: E/MediaPlayer(26201): callback application
04-27 18:31:05.757: E/MediaPlayer(26201): back from callback
04-27 18:31:05.757: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.757: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.757: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.757: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.757: V/MediaPlayer(26201): reset
04-27 18:31:05.757: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.757: V/MediaPlayer(26201): start
04-27 18:31:05.757: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.757: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.757: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.757: E/MediaPlayer(26201): callback application
04-27 18:31:05.757: E/MediaPlayer(26201): back from callback
04-27 18:31:05.761: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.761: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.761: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.761: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.761: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.761: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.761: V/MediaPlayer(26201): reset
04-27 18:31:05.761: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.761: V/MediaPlayer(26201): start
04-27 18:31:05.761: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.761: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.761: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.761: E/MediaPlayer(26201): callback application
04-27 18:31:05.761: E/MediaPlayer(26201): back from callback
04-27 18:31:05.765: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.765: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.765: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.765: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.765: V/MediaPlayer(26201): reset
04-27 18:31:05.765: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.765: V/MediaPlayer(26201): start
04-27 18:31:05.765: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.765: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.765: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.765: E/MediaPlayer(26201): callback application
04-27 18:31:05.765: E/MediaPlayer(26201): back from callback
04-27 18:31:05.765: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.765: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.769: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.769: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.769: V/MediaPlayer(26201): reset
04-27 18:31:05.769: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.769: V/MediaPlayer(26201): start
04-27 18:31:05.769: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.769: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.769: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.769: E/MediaPlayer(26201): callback application
04-27 18:31:05.769: E/MediaPlayer(26201): back from callback
04-27 18:31:05.769: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.769: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.769: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.769: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.769: V/MediaPlayer(26201): reset
04-27 18:31:05.773: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.773: V/MediaPlayer(26201): start
04-27 18:31:05.773: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.773: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.773: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.773: E/MediaPlayer(26201): callback application
04-27 18:31:05.773: E/MediaPlayer(26201): back from callback
04-27 18:31:05.773: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.773: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.773: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.773: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.773: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.773: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.773: V/MediaPlayer(26201): reset
04-27 18:31:05.776: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.776: V/MediaPlayer(26201): start
04-27 18:31:05.776: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.776: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
</code>```

Source Code:

```<code>import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Calendar;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.IBinder;
import android.os.Process;
import android.util.Log;
/**
 * MediaPlayer does not yet support "Shoutcast"-like streaming from external
 * URLs so this class provides a pseudo-streaming function by downloading the
 * content incrementally & playing as soon as we get enough audio in our
 * temporary storage.
 */
public class StreamingMediaPlayer extends Service {

    final static public String AUDIO_MPEG = "audio/mpeg";
    final static public String BITERATE_HEADER = "icy-br";
    public int INTIAL_KB_BUFFER ;
    private Handler handler;
    //= 96*10/8
    final public int BIT = 8;
    final public int SECONDS = 60;
    int bitrate = 56;

    public File downloadingMediaFile;
    final public String DOWNFILE = "downloadingMediaFile";

    public Context context;
    public int counter;
    public int playedcounter;
    public int preparecounter;

    public MediaPlayer mp1;
    public MediaPlayer mp2;
    public boolean mp1prepared;
    public boolean mp2prepared;
    public boolean mp1preparing;
    public boolean mp2preparing;
    public boolean downloadingformp1;
    public boolean downloadingformp2;
    public boolean prepareState;
    public String SONGURL = "";

    // playing is "true" for mp1 and "false" for mp2
    public boolean mp1playing;

    public boolean started;
    public boolean processHasStarted;
    public boolean processHasPaused;
    public boolean regularStream;

    public BufferedInputStream stream;

    public URL url;
    public URLConnection urlConn;

    public String station;
    public String audiourl;

    public Intent startingIntent = null;

    public boolean stopping;
    Thread preparringthread;

    boolean waitingForPlayer;

    // Setup all the variables
    private void setupVars() {
        counter = 0;
        playedcounter = 0;
        preparecounter = 0;

        mp1 = new MediaPlayer();
        mp2 = new MediaPlayer();

        mp1prepared = false;
        mp2prepared = false;
        mp1preparing = false;
        mp2preparing = false;
        downloadingformp1 = false;
        downloadingformp2 = false;
        prepareState = true;
        mp1playing = false;

        started = false;
        processHasStarted = false;
        processHasPaused = true;
        regularStream = false;
        stream = null;

        url = null;
        urlConn = null;

        station = null;
        audiourl = null;

        stopping = false;
        preparringthread = null;

        waitingForPlayer = false;
    }

    // This object will allow other processes to interact with our service
    private final IStreamingMediaPlayer.Stub ourBinder = new IStreamingMediaPlayer.Stub() {
        // String TAG = "IStreamingMediaPlayer.Stub";

        public String getStation() {
            // Log.d(TAG, "getStation");
            return station;
        }

        public String getUrl() {
            // Log.d(TAG, "getUrl");
            return audiourl;
        }

        public boolean playing() {
            // Log.d(TAG, "playing?");
            return isPlaying();
        }

        public boolean pause() {
            // Log.d(TAG, "playing?");
            return isPause();
        }

        public void startAudio() {
            // Log.d(TAG, "startAudio");

            Runnable r = new Runnable() {
                public void run() {
                    onStart(startingIntent, 0);
                }
            };
            new Thread(r).start();

        }

        public void stopAudio() {
            // Log.d(TAG, "stopAudio");
            stop();
        }

    };

    @Override
    public void onCreate() {
        super.onCreate();
        context = this;

    }

    @Override
    public void onStart(Intent intent, int startId) throws NullPointerException {
        super.onStart(intent, startId);

        // final String TAG = "StreamingMediaPlayer - onStart";

        context = this;

        setupVars();

        if (intent.hasExtra("audiourl")) {
            raiseThreadPriority();
            processHasStarted = true;
            processHasPaused = false;

            audiourl = intent.getStringExtra("audiourl");
            station = intent.getStringExtra("station");

            downloadingMediaFile = new File(context.getCacheDir(), DOWNFILE+ counter);
            downloadingMediaFile.deleteOnExit();

            Runnable r = new Runnable() {
                public void run() {
                    try {

                        startStreaming(audiourl);

                    } catch (IOException e) {
                        // Log.d(TAG, e.toString());
                    }
                }
            };
            Thread t = new Thread(r);
            t.start();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mp1.stop();
        mp2.stop();
    }

    @Override
    public IBinder onBind(Intent intent) {

        startingIntent = intent;
        context = this;
        return ourBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        super.onUnbind(intent);

        stopSelf();

        return true;
    }

    /**
     * Progressivly download the media to a temporary location and update the
     * MediaPlayer as new content becomes available.
     */
    public void startStreaming(final String mediaUrl) throws IOException {

        try {
            url = new URL(mediaUrl);
            urlConn = (HttpURLConnection) url.openConnection();
            urlConn.setReadTimeout(1000 * 20);
            urlConn.setConnectTimeout(1000 * 5);
            //The getContentType method is used by the getContent method to determine the type of the remote object; subclasses may find it convenient to override the getContentType method.
            String ctype = urlConn.getContentType();
            if (ctype == null) {
                ctype = "";
            } else {
                ctype = ctype.toLowerCase();
            }

            if (ctype.contains(AUDIO_MPEG) || ctype.equals("")) {

                String temp = urlConn.getHeaderField(BITERATE_HEADER);

                if (temp != null) {
                    bitrate = new Integer(temp).intValue();
                }
            } else {

                stopSelf();
                return;
            }
        }
        catch(NullPointerException ne)
        {

        }
        catch (IOException ioe) {
            // Log.e(TAG, "Could not connect to " + mediaUrl);
            stopSelf();
            return;
        }

        if (!regularStream) {

            INTIAL_KB_BUFFER = bitrate * SECONDS / BIT;

            Runnable r = new Runnable() {
                public void run() {
                    try {
                        downloadAudioIncrement(mediaUrl);
                        Log.i("TAG12344444", "Unable to play");
                        stopSelf();
                        return;
                    } catch (IOException e) {
                        Log.i("TAG123", "Unable to initialize the MediaPlayer for Audio Url = "+mediaUrl, e);
                        stopSelf();
                        return;
                    } catch (NullPointerException e) {

                        stopSelf();
                        return;
                    }
                }
            };
            Thread t = new Thread(r);

            t.start();
        }
    }

    /**
     * Download the url stream to a temporary location and then call the
     * setDataSource for that local file
     */
    public void downloadAudioIncrement(String mediaUrl) throws IOException{

        int bufsizeForDownload = 8 * 1024;
        int bufsizeForfile = 64 * 1024;

        stream = new BufferedInputStream(urlConn.getInputStream(),bufsizeForDownload);
        Log.i("bufsize",Integer.toString(urlConn.getInputStream().available()));

        try{
            if(stream == null || stream.available() == 0){
                stopSelf();
                Log.i("unable to create ","stream null");
                return;
            }
        }catch (NullPointerException e) {
            stopSelf();
            Log.i("return1","return1");
            return;
        }

        BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(downloadingMediaFile), bufsizeForfile);

        byte buf[] = new byte[bufsizeForDownload];
        int totalBytesRead = 0, totalKbRead = 0, numread = 0;

        do {
            if (bout == null) {
                counter++;

                downloadingMediaFile = new File(context.getCacheDir(), DOWNFILE+ counter);
                downloadingMediaFile.deleteOnExit();
                bout = new BufferedOutputStream(new FileOutputStream(downloadingMediaFile), bufsizeForfile);
            }

            try {

                numread = stream.read(buf);
            } catch (IOException e) {

                Log.d("Downloadingfile", "Bad read. Let's quit.");
                // stop();
                Log.i("return2","return2");
                stopSelf();
                 // return;

            }
            catch (NullPointerException e) {
                // Let's get out of here
                e.printStackTrace();
                break;
            }

            if (numread < 0) {

                bout.flush();
                stopSelf();

                Log.i("Bad read from stream", "Bad read from stream3");
                if(stream == null){
                    urlConn = new URL(mediaUrl).openConnection();
                    urlConn.setConnectTimeout(1000 * 30);
                    urlConn.connect();
                    stream = new BufferedInputStream(urlConn.getInputStream(),bufsizeForDownload);

                }else{
                    handler.post(new Runnable() {
                           public void run() {
                               Log.i("Bad read from stream", "Bad read from xyz");

                              context.stopService(startingIntent);
                               Log.i("return3","return3");
                              return;
                           }
                        });

                }

            } else if (numread >= 1) {

                bout.write(buf, 0, numread);

                totalBytesRead += numread;
                totalKbRead += totalBytesRead / 1000;
            }

            if (totalKbRead >= INTIAL_KB_BUFFER && stopping != true) {

                bout.flush();

                bout.close();
                bout = null;
                if (started == false) {
                    Runnable r = new Runnable() {
                        public void run() {
                            setupplayer();
                        }
                    };
                    Thread t = new Thread(r);
                    t.start();
                }

                totalBytesRead = 0;
                totalKbRead = 0;
            }

            if (stopping == true) {
                stream = null;

            }

        } while (stream != null);

    }

    /** oncompletelister for media player **/

    class listener implements MediaPlayer.OnCompletionListener {

        public void onCompletion(MediaPlayer mp) {

            waitingForPlayer = false;

            long timeInMilli = Calendar.getInstance().getTime().getTime();
            long timeToQuit = (1000 * 30) + timeInMilli; // add 30 seconds

            if (mp1playing)
            {
                mp1.reset();
                removefile();
                mp1prepared = false;
                // Log.d(TAG, "mp1 is Free.");
                if (downloadingformp2) {
                    if (mp2preparing && stopping == false) {

                        waitingForPlayer = true;
                    }
                    while (mp2preparing && stopping == false) {
                        if (timeInMilli > timeToQuit) {

                            stopSelf();
                        }
                        timeInMilli = Calendar.getInstance().getTime().getTime();
                    }
                }
            } else {
                mp2.reset();
                removefile();
                mp2prepared = false;

                if (downloadingformp1) {
                    if (mp1preparing && stopping == false) {

                        waitingForPlayer = true;
                    }
                    while (mp1preparing && stopping == false) {
                        if (timeInMilli > timeToQuit) {

                            stopSelf();
                        }
                        timeInMilli = Calendar.getInstance().getTime().getTime();
                    }
                }
            }

            if (waitingForPlayer == true) {
                // we must have been waiting
                waitingForPlayer = false;
            }

            if (stopping == false) {

                if (mp1playing) {

                    mp2.start();

                    mp1playing = false;
                    Runnable r = new Runnable() {
                        public void run() {
                            setupplayer();
                        }
                    };
                    Thread t = new Thread(r);
                    t.start();
                } else {

                    mp1.start();

                    mp1playing = true;
                    Runnable r = new Runnable() {
                        public void run() {
                            setupplayer();
                        }
                    };
                    Thread t = new Thread(r);
                    t.start();
                }
            }
        }
    }

    /** OnPreparedListener for media player **/

    class preparelistener implements MediaPlayer.OnPreparedListener {

        public void onPrepared(MediaPlayer mp) {

            if (prepareState) {
                prepareState = false;
                mp1preparing = false;
                mp1prepared = true;

                if (started == false) {
                    started = true;

                    mp1.start();
                    mp1playing = true;
                    Runnable r = new Runnable() {
                        public void run() {
                            setupplayer();
                        }
                    };
                    Thread t = new Thread(r);
                    t.start();
                }
            } else {
                prepareState = true;
                mp2preparing = false;
                mp2prepared = true;

            }
        }
    };

    /**
     * Set Up player(s)
     */
    public void setupplayer() {
        final String TAG = "setupplayer";

        Runnable r = new Runnable() {
            public void run() {
                try {

                    if (!mp1preparing && !mp1prepared) {

                        while (true) {
                            downloadingformp1 = true;
                            if (started == false)
                                break;
                            if (counter > preparecounter)
                                break;
                        }
                        File f = new File(context.getCacheDir(), DOWNFILE+ preparecounter);
                        FileInputStream ins = new FileInputStream(f);

                        mp1.setDataSource(ins.getFD());
                        mp1.setAudioStreamType(AudioManager.STREAM_MUSIC);//playing for live streaming

                        mp1.setOnCompletionListener(new listener());

                        mp1.setOnPreparedListener(new preparelistener());

                        if (started == false || waitingForPlayer == true){

                        }

                        mp1.prepareAsync();// .prepare();
                        mp1preparing = true;
                        downloadingformp1 = false;
                        preparecounter++;

                    } else if (!mp2preparing && !mp2prepared) {

                        while (true) {
                            downloadingformp2 = true;
                            if (started == false)
                                break;
                            if (counter > preparecounter)
                                break;
                        }
                        File f = new File(context.getCacheDir(), DOWNFILE+ preparecounter);
                        FileInputStream ins = new FileInputStream(f);

                        mp2.setDataSource(ins.getFD());
                        mp2.setAudioStreamType(AudioManager.STREAM_MUSIC);

                        mp2.setOnCompletionListener(new listener());

                        mp2.setOnPreparedListener(new preparelistener());

                        mp2.prepareAsync();
                        mp2preparing = true;
                        downloadingformp2 = false;
                        preparecounter++;

                        // }

                    } else
                        Log.d(TAG, "No Media player is available to setup.");
                        return;

                } catch (FileNotFoundException e) {
                    Log.e(TAG, e.toString());
                    Log.e(TAG,"Can't find file. Android must have deleted it on a clean up ");
                    stop();

                    return;

                } catch (IllegalStateException e) {
                    Log.e(TAG, e.toString());
                    stop();

                } catch (IOException e) {
                    Log.e(TAG, e.toString());
                    stop();

                }
            }

        };
        preparringthread = new Thread(r);
        preparringthread.start();

        try {

            preparringthread.join();
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
    }

    private void removefile() {

        File temp = new File(context.getCacheDir(), DOWNFILE + playedcounter);

        temp.delete();
        playedcounter++;
    }

    public boolean stop() {
        final String TAG = "STOP";

        stopping = true;
        try {

            if (mp1.isPlaying()){
                if (!(stream == null)) {
                    Log.i("IN STOP", "MP1 is nill");
                    stopSelf();
                }
                mp1.stop();
            }

            if (mp2.isPlaying()){
                Log.i("IN STOP", "MP2 is nill");

                if (!(stream == null)){
                    stopSelf();
                }
                mp2.stop();
            }

        } catch (Exception e) {
            Log.e(TAG, "error stopping players");
        }

        if (stream != null) {

            try {
                stream.close();

            } catch (IOException e) {
                Log.e(TAG, "error closing open connection");
            }
        }
        stream = null;

        processHasStarted = false;
        processHasPaused = true;
        if (preparringthread != null) {
            preparringthread.interrupt();
        }

        stopSelf();

        return true;
    }

    public boolean isPlaying() {

        return processHasStarted;
    }

    public boolean isPause() {

        return processHasPaused;
    }

    private void raiseThreadPriority() {

        Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO);

    }
}
</code>```

答:
Not sure is it actual now or not, but MediaPlayer can play live streams (at least audio/mpeg and audio/aacp). You don't need to predownload the content. Just call</p>

```<code>MediaPlayer.setDataSource("http://123.176.41.8:8256");
</code>```

Body:
I developed Shoutcastinternet Radio Streaming(Stream URL:http://123.176.41.8:8256) in Andriod and i'm able to stream and play Successfully.

But the problem is: when i execute my application,I'm able to stream and play Continuously for someextend(20min,halfanhour etc...),

after that the stream is getting stoped(I'm not ableto play the stream),Could any one help?

I logged the Error,after Stream get Stopped.

The Error is:
D/dalvikvm(1238): GC_FOR_MALLOC freed 51742 objects / 1928072 bytes in 80ms(I'm repeating this statement in the log file while running my application on real Device)

Update:

 Exception:

  04-27 18:31:05.753: V/MediaPlayer(26201): start
04-27 18:31:05.753: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.753: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.753: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.753: E/MediaPlayer(26201): callback application
04-27 18:31:05.753: E/MediaPlayer(26201): back from callback
04-27 18:31:05.753: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.753: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.757: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.757: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.757: V/MediaPlayer(26201): reset
04-27 18:31:05.757: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.757: V/MediaPlayer(26201): start
04-27 18:31:05.757: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.757: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.757: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.757: E/MediaPlayer(26201): callback application
04-27 18:31:05.757: E/MediaPlayer(26201): back from callback
04-27 18:31:05.757: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.757: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.757: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.757: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.757: V/MediaPlayer(26201): reset
04-27 18:31:05.757: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.757: V/MediaPlayer(26201): start
04-27 18:31:05.757: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.757: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.757: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.757: E/MediaPlayer(26201): callback application
04-27 18:31:05.757: E/MediaPlayer(26201): back from callback
04-27 18:31:05.761: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.761: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.761: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.761: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.761: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.761: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.761: V/MediaPlayer(26201): reset
04-27 18:31:05.761: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.761: V/MediaPlayer(26201): start
04-27 18:31:05.761: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.761: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.761: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.761: E/MediaPlayer(26201): callback application
04-27 18:31:05.761: E/MediaPlayer(26201): back from callback
04-27 18:31:05.765: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.765: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.765: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.765: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.765: V/MediaPlayer(26201): reset
04-27 18:31:05.765: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.765: V/MediaPlayer(26201): start
04-27 18:31:05.765: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.765: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.765: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.765: E/MediaPlayer(26201): callback application
04-27 18:31:05.765: E/MediaPlayer(26201): back from callback
04-27 18:31:05.765: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.765: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.769: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.769: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.769: V/MediaPlayer(26201): reset
04-27 18:31:05.769: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.769: V/MediaPlayer(26201): start
04-27 18:31:05.769: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.769: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.769: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.769: E/MediaPlayer(26201): callback application
04-27 18:31:05.769: E/MediaPlayer(26201): back from callback
04-27 18:31:05.769: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.769: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.769: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.769: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.769: V/MediaPlayer(26201): reset
04-27 18:31:05.773: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.773: V/MediaPlayer(26201): start
04-27 18:31:05.773: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.773: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0
04-27 18:31:05.773: E/MediaPlayer(26201): error (-38, 0)
04-27 18:31:05.773: E/MediaPlayer(26201): callback application
04-27 18:31:05.773: E/MediaPlayer(26201): back from callback
04-27 18:31:05.773: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.773: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.773: E/setupplayer(26201): java.io.FileNotFoundException: /data/data/com.torilt/cache/downloadingMediaFile591 (No such file or directory)
04-27 18:31:05.773: E/setupplayer(26201): Can't find file. Android must have deleted it on a clean up
04-27 18:31:05.773: E/MediaPlayer(26201): Error (-38,0)
04-27 18:31:05.773: V/MediaPlayer-JNI(26201): reset
04-27 18:31:05.773: V/MediaPlayer(26201): reset
04-27 18:31:05.776: V/MediaPlayer-JNI(26201): start
04-27 18:31:05.776: V/MediaPlayer(26201): start
04-27 18:31:05.776: E/MediaPlayer(26201): start called in state 1
04-27 18:31:05.776: E/MediaPlayer(26201): message received msg=100, ext1=-38, ext2=0

Source Code:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Calendar;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.IBinder;
import android.os.Process;
import android.util.Log;
/**
 * MediaPlayer does not yet support "Shoutcast"-like streaming from external
 * URLs so this class provides a pseudo-streaming function by downloading the
 * content incrementally & playing as soon as we get enough audio in our
 * temporary storage.
 */
public class StreamingMediaPlayer extends Service {

    final static public String AUDIO_MPEG = "audio/mpeg";
    final static public String BITERATE_HEADER = "icy-br";
    public int INTIAL_KB_BUFFER ;
    private Handler handler;
    //= 96*10/8
    final public int BIT = 8;
    final public int SECONDS = 60;
    int bitrate = 56;

    public File downloadingMediaFile;
    final public String DOWNFILE = "downloadingMediaFile";

    public Context context;
    public int counter;
    public int playedcounter;
    public int preparecounter;

    public MediaPlayer mp1;
    public MediaPlayer mp2;
    public boolean mp1prepared;
    public boolean mp2prepared;
    public boolean mp1preparing;
    public boolean mp2preparing;
    public boolean downloadingformp1;
    public boolean downloadingformp2;
    public boolean prepareState;
    public String SONGURL = "";

    // playing is "true" for mp1 and "false" for mp2
    public boolean mp1playing;

    public boolean started;
    public boolean processHasStarted;
    public boolean processHasPaused;
    public boolean regularStream;

    public BufferedInputStream stream;

    public URL url;
    public URLConnection urlConn;

    public String station;
    public String audiourl;

    public Intent startingIntent = null;

    public boolean stopping;
    Thread preparringthread;

    boolean waitingForPlayer;

    // Setup all the variables
    private void setupVars() {
        counter = 0;
        playedcounter = 0;
        preparecounter = 0;

        mp1 = new MediaPlayer();
        mp2 = new MediaPlayer();

        mp1prepared = false;
        mp2prepared = false;
        mp1preparing = false;
        mp2preparing = false;
        downloadingformp1 = false;
        downloadingformp2 = false;
        prepareState = true;
        mp1playing = false;

        started = false;
        processHasStarted = false;
        processHasPaused = true;
        regularStream = false;
        stream = null;

        url = null;
        urlConn = null;

        station = null;
        audiourl = null;

        stopping = false;
        preparringthread = null;

        waitingForPlayer = false;
    }

    // This object will allow other processes to interact with our service
    private final IStreamingMediaPlayer.Stub ourBinder = new IStreamingMediaPlayer.Stub() {
        // String TAG = "IStreamingMediaPlayer.Stub";

        public String getStation() {
            // Log.d(TAG, "getStation");
            return station;
        }

        public String getUrl() {
            // Log.d(TAG, "getUrl");
            return audiourl;
        }

        public boolean playing() {
            // Log.d(TAG, "playing?");
            return isPlaying();
        }

        public boolean pause() {
            // Log.d(TAG, "playing?");
            return isPause();
        }

        public void startAudio() {
            // Log.d(TAG, "startAudio");

            Runnable r = new Runnable() {
                public void run() {
                    onStart(startingIntent, 0);
                }
            };
            new Thread(r).start();

        }

        public void stopAudio() {
            // Log.d(TAG, "stopAudio");
            stop();
        }

    };

    @Override
    public void onCreate() {
        super.onCreate();
        context = this;

    }

    @Override
    public void onStart(Intent intent, int startId) throws NullPointerException {
        super.onStart(intent, startId);

        // final String TAG = "StreamingMediaPlayer - onStart";

        context = this;

        setupVars();

        if (intent.hasExtra("audiourl")) {
            raiseThreadPriority();
            processHasStarted = true;
            processHasPaused = false;

            audiourl = intent.getStringExtra("audiourl");
            station = intent.getStringExtra("station");

            downloadingMediaFile = new File(context.getCacheDir(), DOWNFILE+ counter);
            downloadingMediaFile.deleteOnExit();

            Runnable r = new Runnable() {
                public void run() {
                    try {

                        startStreaming(audiourl);

                    } catch (IOException e) {
                        // Log.d(TAG, e.toString());
                    }
                }
            };
            Thread t = new Thread(r);
            t.start();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mp1.stop();
        mp2.stop();
    }

    @Override
    public IBinder onBind(Intent intent) {

        startingIntent = intent;
        context = this;
        return ourBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        super.onUnbind(intent);

        stopSelf();

        return true;
    }

    /**
     * Progressivly download the media to a temporary location and update the
     * MediaPlayer as new content becomes available.
     */
    public void startStreaming(final String mediaUrl) throws IOException {

        try {
            url = new URL(mediaUrl);
            urlConn = (HttpURLConnection) url.openConnection();
            urlConn.setReadTimeout(1000 * 20);
            urlConn.setConnectTimeout(1000 * 5);
            //The getContentType method is used by the getContent method to determine the type of the remote object; subclasses may find it convenient to override the getContentType method.
            String ctype = urlConn.getContentType();
            if (ctype == null) {
                ctype = "";
            } else {
                ctype = ctype.toLowerCase();
            }

            if (ctype.contains(AUDIO_MPEG) || ctype.equals("")) {

                String temp = urlConn.getHeaderField(BITERATE_HEADER);

                if (temp != null) {
                    bitrate = new Integer(temp).intValue();
                }
            } else {

                stopSelf();
                return;
            }
        }
        catch(NullPointerException ne)
        {

        }
        catch (IOException ioe) {
            // Log.e(TAG, "Could not connect to " + mediaUrl);
            stopSelf();
            return;
        }

        if (!regularStream) {

            INTIAL_KB_BUFFER = bitrate * SECONDS / BIT;

            Runnable r = new Runnable() {
                public void run() {
                    try {
                        downloadAudioIncrement(mediaUrl);
                        Log.i("TAG12344444", "Unable to play");
                        stopSelf();
                        return;
                    } catch (IOException e) {
                        Log.i("TAG123", "Unable to initialize the MediaPlayer for Audio Url = "+mediaUrl, e);
                        stopSelf();
                        return;
                    } catch (NullPointerException e) {

                        stopSelf();
                        return;
                    }
                }
            };
            Thread t = new Thread(r);

            t.start();
        }
    }

    /**
     * Download the url stream to a temporary location and then call the
     * setDataSource for that local file
     */
    public void downloadAudioIncrement(String mediaUrl) throws IOException{

        int bufsizeForDownload = 8 * 1024;
        int bufsizeForfile = 64 * 1024;

        stream = new BufferedInputStream(urlConn.getInputStream(),bufsizeForDownload);
        Log.i("bufsize",Integer.toString(urlConn.getInputStream().available()));

        try{
            if(stream == null || stream.available() == 0){
                stopSelf();
                Log.i("unable to create ","stream null");
                return;
            }
        }catch (NullPointerException e) {
            stopSelf();
            Log.i("return1","return1");
            return;
        }

        BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(downloadingMediaFile), bufsizeForfile);

        byte buf[] = new byte[bufsizeForDownload];
        int totalBytesRead = 0, totalKbRead = 0, numread = 0;

        do {
            if (bout == null) {
                counter++;

                downloadingMediaFile = new File(context.getCacheDir(), DOWNFILE+ counter);
                downloadingMediaFile.deleteOnExit();
                bout = new BufferedOutputStream(new FileOutputStream(downloadingMediaFile), bufsizeForfile);
            }

            try {

                numread = stream.read(buf);
            } catch (IOException e) {

                Log.d("Downloadingfile", "Bad read. Let's quit.");
                // stop();
                Log.i("return2","return2");
                stopSelf();
                 // return;

            }
            catch (NullPointerException e) {
                // Let's get out of here
                e.printStackTrace();
                break;
            }

            if (numread < 0) {

                bout.flush();
                stopSelf();

                Log.i("Bad read from stream", "Bad read from stream3");
                if(stream == null){
                    urlConn = new URL(mediaUrl).openConnection();
                    urlConn.setConnectTimeout(1000 * 30);
                    urlConn.connect();
                    stream = new BufferedInputStream(urlConn.getInputStream(),bufsizeForDownload);

                }else{
                    handler.post(new Runnable() {
                           public void run() {
                               Log.i("Bad read from stream", "Bad read from xyz");

                              context.stopService(startingIntent);
                               Log.i("return3","return3");
                              return;
                           }
                        });

                }

            } else if (numread >= 1) {

                bout.write(buf, 0, numread);

                totalBytesRead += numread;
                totalKbRead += totalBytesRead / 1000;
            }

            if (totalKbRead >= INTIAL_KB_BUFFER && stopping != true) {

                bout.flush();

                bout.close();
                bout = null;
                if (started == false) {
                    Runnable r = new Runnable() {
                        public void run() {
                            setupplayer();
                        }
                    };
                    Thread t = new Thread(r);
                    t.start();
                }

                totalBytesRead = 0;
                totalKbRead = 0;
            }

            if (stopping == true) {
                stream = null;

            }

        } while (stream != null);

    }

    /** oncompletelister for media player **/

    class listener implements MediaPlayer.OnCompletionListener {

        public void onCompletion(MediaPlayer mp) {

            waitingForPlayer = false;

            long timeInMilli = Calendar.getInstance().getTime().getTime();
            long timeToQuit = (1000 * 30) + timeInMilli; // add 30 seconds

            if (mp1playing)
            {
                mp1.reset();
                removefile();
                mp1prepared = false;
                // Log.d(TAG, "mp1 is Free.");
                if (downloadingformp2) {
                    if (mp2preparing && stopping == false) {

                        waitingForPlayer = true;
                    }
                    while (mp2preparing && stopping == false) {
                        if (timeInMilli > timeToQuit) {

                            stopSelf();
                        }
                        timeInMilli = Calendar.getInstance().getTime().getTime();
                    }
                }
            } else {
                mp2.reset();
                removefile();
                mp2prepared = false;

                if (downloadingformp1) {
                    if (mp1preparing && stopping == false) {

                        waitingForPlayer = true;
                    }
                    while (mp1preparing && stopping == false) {
                        if (timeInMilli > timeToQuit) {

                            stopSelf();
                        }
                        timeInMilli = Calendar.getInstance().getTime().getTime();
                    }
                }
            }

            if (waitingForPlayer == true) {
                // we must have been waiting
                waitingForPlayer = false;
            }

            if (stopping == false) {

                if (mp1playing) {

                    mp2.start();

                    mp1playing = false;
                    Runnable r = new Runnable() {
                        public void run() {
                            setupplayer();
                        }
                    };
                    Thread t = new Thread(r);
                    t.start();
                } else {

                    mp1.start();

                    mp1playing = true;
                    Runnable r = new Runnable() {
                        public void run() {
                            setupplayer();
                        }
                    };
                    Thread t = new Thread(r);
                    t.start();
                }
            }
        }
    }

    /** OnPreparedListener for media player **/

    class preparelistener implements MediaPlayer.OnPreparedListener {

        public void onPrepared(MediaPlayer mp) {

            if (prepareState) {
                prepareState = false;
                mp1preparing = false;
                mp1prepared = true;

                if (started == false) {
                    started = true;

                    mp1.start();
                    mp1playing = true;
                    Runnable r = new Runnable() {
                        public void run() {
                            setupplayer();
                        }
                    };
                    Thread t = new Thread(r);
                    t.start();
                }
            } else {
                prepareState = true;
                mp2preparing = false;
                mp2prepared = true;

            }
        }
    };

    /**
     * Set Up player(s)
     */
    public void setupplayer() {
        final String TAG = "setupplayer";

        Runnable r = new Runnable() {
            public void run() {
                try {

                    if (!mp1preparing && !mp1prepared) {

                        while (true) {
                            downloadingformp1 = true;
                            if (started == false)
                                break;
                            if (counter > preparecounter)
                                break;
                        }
                        File f = new File(context.getCacheDir(), DOWNFILE+ preparecounter);
                        FileInputStream ins = new FileInputStream(f);

                        mp1.setDataSource(ins.getFD());
                        mp1.setAudioStreamType(AudioManager.STREAM_MUSIC);//playing for live streaming

                        mp1.setOnCompletionListener(new listener());

                        mp1.setOnPreparedListener(new preparelistener());

                        if (started == false || waitingForPlayer == true){

                        }

                        mp1.prepareAsync();// .prepare();
                        mp1preparing = true;
                        downloadingformp1 = false;
                        preparecounter++;

                    } else if (!mp2preparing && !mp2prepared) {

                        while (true) {
                            downloadingformp2 = true;
                            if (started == false)
                                break;
                            if (counter > preparecounter)
                                break;
                        }
                        File f = new File(context.getCacheDir(), DOWNFILE+ preparecounter);
                        FileInputStream ins = new FileInputStream(f);

                        mp2.setDataSource(ins.getFD());
                        mp2.setAudioStreamType(AudioManager.STREAM_MUSIC);

                        mp2.setOnCompletionListener(new listener());

                        mp2.setOnPreparedListener(new preparelistener());

                        mp2.prepareAsync();
                        mp2preparing = true;
                        downloadingformp2 = false;
                        preparecounter++;

                        // }

                    } else
                        Log.d(TAG, "No Media player is available to setup.");
                        return;

                } catch (FileNotFoundException e) {
                    Log.e(TAG, e.toString());
                    Log.e(TAG,"Can't find file. Android must have deleted it on a clean up ");
                    stop();

                    return;

                } catch (IllegalStateException e) {
                    Log.e(TAG, e.toString());
                    stop();

                } catch (IOException e) {
                    Log.e(TAG, e.toString());
                    stop();

                }
            }

        };
        preparringthread = new Thread(r);
        preparringthread.start();

        try {

            preparringthread.join();
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
    }

    private void removefile() {

        File temp = new File(context.getCacheDir(), DOWNFILE + playedcounter);

        temp.delete();
        playedcounter++;
    }

    public boolean stop() {
        final String TAG = "STOP";

        stopping = true;
        try {

            if (mp1.isPlaying()){
                if (!(stream == null)) {
                    Log.i("IN STOP", "MP1 is nill");
                    stopSelf();
                }
                mp1.stop();
            }

            if (mp2.isPlaying()){
                Log.i("IN STOP", "MP2 is nill");

                if (!(stream == null)){
                    stopSelf();
                }
                mp2.stop();
            }

        } catch (Exception e) {
            Log.e(TAG, "error stopping players");
        }

        if (stream != null) {

            try {
                stream.close();

            } catch (IOException e) {
                Log.e(TAG, "error closing open connection");
            }
        }
        stream = null;

        processHasStarted = false;
        processHasPaused = true;
        if (preparringthread != null) {
            preparringthread.interrupt();
        }

        stopSelf();

        return true;
    }

    public boolean isPlaying() {

        return processHasStarted;
    }

    public boolean isPause() {

        return processHasPaused;
    }

    private void raiseThreadPriority() {

        Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO);

    }
}

Body:
Not sure is it actual now or not, but MediaPlayer can play live streams (at least audio/mpeg and audio/aacp). You don't need to predownload the content. Just call

MediaPlayer.setDataSource("http://123.176.41.8:8256");


来源: stackexchange

问:
Using CASE WHEN
I have the following table:

```<code>Email | value | group
 a    |   1   |   x
 a    |   2   |   y
 a    |   3   |   y
 b    |   3   |   z
</code>```

I previously wrote code to pull the sum of values by distinct email in each group, to get this:

```<code>Email | value | group
 a    |   1   |   x
 a    |   5   |   y
 b    |   3   |   z
</code>```

The code looked like this:

```<code> SELECT distinct email,
        group,
        sum (value)
  from t
 group by email, group
</code>```

Now, I want to sum by groups of groups using CASE, to get this output:

```<code> Email | value | super_group
 a     |   6    |   x_y
 b     |   3    |   z
</code>```

But this code doesn't work:

```<code> SELECT distinct email,
        CASE when group in (x,y)
             then 'x_y'
             else 'z'
        end as super_group,
        sum (value)
   from t
  group by email, super_group
</code>```

答:
If you are using a newer version of Teradata you can use XMLAGG() to do this:</p>

```<code>SELECT
    email,
    sum(value),
    trim(trailing '_' FROM (XMLAGG(group || '_' ORDER BY group) (VARCHAR(50))))
FROM table
GROUP BY 1
</code>```

ContentLicense: CC BY-SA 3.0

Title: Using CASE WHEN

Body:
I have the following table:

Email | value | group
 a    |   1   |   x
 a    |   2   |   y
 a    |   3   |   y
 b    |   3   |   z

I previously wrote code to pull the sum of values by distinct email in each group, to get this:

Email | value | group
 a    |   1   |   x
 a    |   5   |   y
 b    |   3   |   z

The code looked like this:

 SELECT distinct email,
        group,
        sum (value)
  from t
 group by email, group

Now, I want to sum by groups of groups using CASE, to get this output:

 Email | value | super_group
 a     |   6    |   x_y
 b     |   3    |   z

But this code doesn't work:

 SELECT distinct email,
        CASE when group in (x,y)
             then 'x_y'
             else 'z'
        end as super_group,
        sum (value)
   from t
  group by email, super_group

Body:
If you are using a newer version of Teradata you can use XMLAGG() to do this:

SELECT
    email,
    sum(value),
    trim(trailing '_' FROM (XMLAGG(group || '_' ORDER BY group) (VARCHAR(50))))
FROM table
GROUP BY 1


问:
Display the data I get from ajax on view
This is the modal where I want to display the value I get from ajax data but it's not working. I have the id="view_name" on span element. I don't know what the problem is it won't display

This is the code that triggers the fun_view function:

```<code><td>
    <a href="" data-id="" class="display" data-toggle="modal" data-target="#myModal" onclick="fun_view('{{ $dat->id }},{{ $dat->name }},{{ $dat->company_name }}, {{ $dat->mobile_phone }}, {{ $dat->timezone }}, {{ $dat->best_time_to_call }}')"><?php echo $dat->name;?></a>
</td>

<div class="modal-body">
    <p><b>Name : </b><span id="view_name" class="text-success"></span></p>
    <p><b>Company Name : </b><span id="view_company_name" class="text-success"></span></p>
    <p><b>Mobile Phone : </b><span id="view_mobile" class="text-success"></span></p>
</div>

<script>
function fun_view(id,name,company_name,mobile_phone,timezone,best_time_to_call)
{
    var view_url = $("#hidden_view").val();

    $.ajax({
        url: view_url,
        type:"GET",
        data:
        {
            "id": id,
            "name": name,
            "company_name": company_name,
            "mobile_phone": mobile_phone,
            "timezone": timezone,
            "best_time_to_call": best_time_to_call
        },
        success: function(result){
          //when I alert(result.name) it says undefined
          $("#view_name").text(result.name);
          $("#view_company_name").text(result.company_name);
          $("#view_mobile").text(result.mobile_phone);
        }
    });
}
</script>
</code>```

答:
Add datatype just to make sure that the ajax response is in JSON object
 and i'm wondering about the selector $('#hidden_view') maybe you have some CSS that hides it.

$.ajax({

```<code>    url: view_url,
    type:"GET",
    datatype: 'JSON',
    data: {"id":id, "name":name, "company_name":company_name, "mobile_phone":mobile_phone, "timezone":timezone, "best_time_to_call":best_time_to_call },
    success: function(result){
      //when i alert(result.name) it says undefined
      $("#view_name").text(result.name);
      $("#view_company_name").text(result.company_name);
      $("#view_mobile").text(result.mobile_phone);
    }
</code>```

});

try the above code

Body:
This is the modal where I want to display the value I get from ajax data but it's not working. I have the id="view_name" on span element. I don't know what the problem is it won't display

This is the code that triggers the fun_view function:

    id }},{{ $dat->name }},{{ $dat->company_name }}, {{ $dat->mobile_phone }}, {{ $dat->timezone }}, {{ $dat->best_time_to_call }}')"><?php echo $dat->name;?>

Name :

Company Name :

Mobile Phone :

Body:
Add datatype just to make sure that the ajax response is in JSON object
 and i'm wondering about the selector $('#hidden_view') maybe you have some CSS that hides it.

$.ajax({

    url: view_url,
    type:"GET",
    datatype: 'JSON',
    data: {"id":id, "name":name, "company_name":company_name, "mobile_phone":mobile_phone, "timezone":timezone, "best_time_to_call":best_time_to_call },
    success: function(result){
      //when i alert(result.name) it says undefined
      $("#view_name").text(result.name);
      $("#view_company_name").text(result.company_name);
      $("#view_mobile").text(result.mobile_phone);
    }

});

try the above code


问:
server tomcat v8.0 server at localhost failed to start
I seem to have a problem with my web.xml file.
every time I run the Apache tomcat 8 server, it gives this error:
server tomcat v8.0 server at localhost failed to start.

when I removed the servlets of the xml file, the server worked!!
my web.xml is as follow:

```<code><?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>ZiyadA00191914</display-name>

  <servlet>
    <servlet-name>RegisterServlet</servlet-name>
    <servlet-class>controllers.RegisterServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>RegisterServlet</servlet-name>
    <url-pattern>/RegisterServlet</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>controllers.LoginServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
  </servlet-mapping>

    <servlet>
    <servlet-name>ListEventMainServlet</servlet-name>
    <servlet-class>controllers.ListEventMainServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>ListEventMainServlet</servlet-name>
    <url-pattern>/ListEventMainServlet</url-pattern>
  </servlet-mapping>

    <servlet>
    <servlet-name>ListEventByCategory</servlet-name>
    <servlet-class>controllers.ListEventByCategory</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>ListEventByCategory</servlet-name>
    <url-pattern>/ListEventByCategory</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>CartServlet</servlet-name>
    <servlet-class>controllers.CartServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>CartServlet</servlet-name>
    <url-pattern>/CartServlet</url-pattern>
  </servlet-mapping>

    <servlet>
    <servlet-name>OrderServlet</servlet-name>
    <servlet-class>controllers.OrderServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>OrderServlet</servlet-name>
    <url-pattern>/OrderServlet</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>FeedbackServlet</servlet-name>
    <servlet-class>controllers.FeedbackServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>FeedbackServlet</servlet-name>
    <url-pattern>/FeedbackServlet</url-pattern>
  </servlet-mapping>

    <servlet>
    <servlet-name>ShippingServlet</servlet-name>
    <servlet-class>controllers.ShippingServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>ShippingServlet</servlet-name>
    <url-pattern>/ShippingServlet</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>LogoutServlet</servlet-name>
    <servlet-class>controllers.LogoutServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>LogoutServlet</servlet-name>
    <url-pattern>/LogoutServlet</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>Driver.jsp</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>main.jsp</welcome-file>
    <welcome-file>listEvents.jsp</welcome-file>
  </welcome-file-list>
</web-app>
</code>```

any suggestion to get it working without removing code of the xml file ?

Thanks in advance guys.

答:
one reason for this problem is the problems in web.xml file...

I also got this problem, i resolved it.

Step to resolve this problem:

1-  Check every servlet class name is correct(fully qualified class name )

2- for checking correct class name go on class name press ctrl and move the pointer on that class name if class name giving hyperlink then class name is correct otherwise you have to change with appropriate class name.

3- check jar you added in project are correct and working

4- after all this changes refresh the project and run it..

it works....

Body:
I seem to have a problem with my web.xml file.
every time I run the Apache tomcat 8 server, it gives this error:
server tomcat v8.0 server at localhost failed to start.

when I removed the servlets of the xml file, the server worked!!
my web.xml is as follow:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>ZiyadA00191914</display-name>

  <servlet>
    <servlet-name>RegisterServlet</servlet-name>
    <servlet-class>controllers.RegisterServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>RegisterServlet</servlet-name>
    <url-pattern>/RegisterServlet</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>controllers.LoginServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
  </servlet-mapping>

    <servlet>
    <servlet-name>ListEventMainServlet</servlet-name>
    <servlet-class>controllers.ListEventMainServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>ListEventMainServlet</servlet-name>
    <url-pattern>/ListEventMainServlet</url-pattern>
  </servlet-mapping>

    <servlet>
    <servlet-name>ListEventByCategory</servlet-name>
    <servlet-class>controllers.ListEventByCategory</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>ListEventByCategory</servlet-name>
    <url-pattern>/ListEventByCategory</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>CartServlet</servlet-name>
    <servlet-class>controllers.CartServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>CartServlet</servlet-name>
    <url-pattern>/CartServlet</url-pattern>
  </servlet-mapping>

    <servlet>
    <servlet-name>OrderServlet</servlet-name>
    <servlet-class>controllers.OrderServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>OrderServlet</servlet-name>
    <url-pattern>/OrderServlet</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>FeedbackServlet</servlet-name>
    <servlet-class>controllers.FeedbackServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>FeedbackServlet</servlet-name>
    <url-pattern>/FeedbackServlet</url-pattern>
  </servlet-mapping>

    <servlet>
    <servlet-name>ShippingServlet</servlet-name>
    <servlet-class>controllers.ShippingServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>ShippingServlet</servlet-name>
    <url-pattern>/ShippingServlet</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>LogoutServlet</servlet-name>
    <servlet-class>controllers.LogoutServlet</servlet-class>
  </servlet>

<servlet-mapping>
    <servlet-name>LogoutServlet</servlet-name>
    <url-pattern>/LogoutServlet</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>Driver.jsp</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>main.jsp</welcome-file>
    <welcome-file>listEvents.jsp</welcome-file>
  </welcome-file-list>
</web-app>

any suggestion to get it working without removing code of the xml file ?

Thanks in advance guys.


问:
Looking for average BGR values for each column in each color
We are working on a code that looks at a 96-well plate. We have the centers coordinates of each well. We then created a for loop that would allow us get the BGR value of each well. However, we need to somehow organize each column and average those values. I believe that we are getting an error from the first loop. With this one, it seems like the function only goes through the first loop and not the second one. When I run it, I get 3 values (assuming to be bgr values) and then proceeds to push out the averages. It also seems to repeat some average values. Any suggestions to what I can change, or errors at first-look. I will provide the image and legend below.

Links to images are:
http://imgur.com/Eb87ZxW (the image was scaled, so the coordinates may not work with the uploaded image)
http://imgur.com/P4tPPXX

```<code>import cv2, numpy as np, sys

#filename will be taken from the command line and process as the image variable
#filename= sys.argv([1])
img = cv2.imread('greenandblueplate.jpg')

#centroids
wells = [img[110,97], img[184,97], img[254,97], img[324,97], img[396,96], img[466,97], #columnH 12-7
         img[537,96], img[607,97], img[680,96], img[750,97], img[820,96], img[891,97], #columnH 6-1
         img[110,165],img[184,165],img[254,165],img[324,165],img[396,165],img[466,165], #columnG 12-7
         img[537,165],img[607,165],img[680,165],img[750,166],img[820,165],img[891,165], #columnG 6-1
         img[110,235],img[184,235],img[254,235],img[324,235],img[396,235],img[466,235], #columnF 12-7
         img[537,235],img[607,235],img[680,235],img[750,235],img[820,235],img[891,235], #columnF 6-1
         img[110,305],img[184,305],img[254,305],img[324,305],img[396,305],img[466,305], #columnE 12-7
         img[537,305],img[607,305],img[680,305],img[750,305],img[820,305],img[891,305], #columnE 6-1
         img[110,373],img[184,373],img[254,373],img[324,373],img[396,373],img[466,373], #columnD 12-7
         img[537,373],img[607,373],img[680,373],img[750,372],img[820,373],img[891,373], #columnD 6-1
         img[110,442],img[184,442],img[254,442],img[324,442],img[396,442],img[466,442], #columnC 12-7
         img[537,442],img[607,442],img[680,442],img[750,443],img[820,442],img[891,442], #columnC 6-1
         img[109,511],img[184,511],img[254,511],img[324,511],img[396,511],img[466,511], #columnB 12-7
         img[537,512],img[607,512],img[680,511],img[750,511],img[820,511],img[891,511], #columnB 6-1
         img[109,582],img[184,582],img[254,582],img[324,581],img[396,582],img[466,582], #columnA 12-7
         img[537,581],img[607,582],img[680,582],img[750,581],img[820,582],img[891,582]] #columnA 6-1

bAvgFilledWells = []
gAvgFilledWells = []
rAvgFilledWells = []

#filtering out the centroids that are not needed
#and getting the bgr values for the first color on the plate
for center in wells:
    if center[1] > 124:
        if center[0] < 360:
            b = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 0]
            g = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 1]
            r = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 2]
            bAvg = np.mean(b)
            gAvg = np.mean(g)
            rAvg = np.mean(r)

            bAvgFilledWells.append(bAvg)
            gAvgFilledWells.append(gAvg)
            rAvgFilledWells.append(rAvg)
            print(center)
            print("For the first color, average value for blue is:", bAvg)
            print("For the first color, average value for green is:", gAvg)
            print("For the first color, average value for red is:", rAvg)

bAvgFilledWells2 = []
gAvgFilledWells2 = []
rAvgFilledWells2 = []

#filtering out the centroids that are not needed
#and getting the bgr values for the second color on the plate
for center in wells:
    if center[1] > 124:
        if center[0] > 360 and center[0] < 642:
            b2 = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 0]
            g2 = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 1]
            r2 = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 2]
            bAvg2 = np.mean(b2)
            gAvg2 = np.mean(g2)
            rAvg2 = np.mean(r2)

            print(center)
            print("For the second color, average value for blue is:", bAvg2)
            print("For the second color, average value for green is:", gAvg2)
            print("For the second color, average value for blue is:", rAvg2)
            bAvgFilledWells2.append(bAvg2)
            gAvgFilledWells2.append(gAvg2)
            rAvgFilledWells2.append(rAvg2)
</code>```

答:
Here's how I would rewrite your code:</p>

```<code>import cv2
from itertools import product
import numpy as np
import sys

# image coordinates
ROWS = (891, 820, 750, 680, 607, 537, 466, 396, 324, 254, 184, 110)   # rows 1..12
COLS = (582, 511, 442, 373, 305, 235, 165, 97)                        # cols A..H

def get_rect_avg_color(img, x, y, w=8, h=8):
    """
    Return the BGR average color of a rectangular area of the image
      centered on (x,y) with width w and height h
    """
    half_w = w // 2
    half_h = h // 2
    # extract the rectangular area
    rect = img[x - half_w: x + (w - half_w) + 1, y - half_h: y + (h - half_h) + 1]
    # average each channel independantly
    avg_col = rect.mean(axis=(0,1))
    return avg_col    # returns [avg_b, avg_g, avg_r]

def get_cells_avg_color(img, cells):
    """
    Return the BGR average color of a list of cells
    """
    cell_colors = np.vstack(get_rect_avg_color(img, *cell) for cell in cells)
    return cell_colors.mean(axis=0)    # returns [avg_b, avg_g, avg_r]

def get_cells(col_from, col_to, row_from, row_to):
    """
    Return a list of all cells in a rectangular block

    col_from, col_to  in "A".."H"
    row_from, row_to  in 1..12

    col_to and row_to are inclusive
    """
    col_from  = ord(col_from.upper()) - ord("A")
    col_to    = ord(col_to  .upper()) - ord("A")
    col_from, col_to = min(col_from, col_to), max(col_from, col_to)
    row_from -= 1
    row_to   -= 1
    row_from, row_to = min(row_from, row_to), max(row_from, row_to)
    return product(ROWS[row_from:row_to + 1], COLS[col_from:col_to + 1])

def main(img_fname):
    img = cv2.imread(img_fname)

    first_cells = get_cells("A", "G", 9, 12)
    first_avg = get_cells_avg_color(img, first_cells)
    print("First color average: blue {:0.2f}, green {:0.2f}, red {:0.2f}".format(*first_avg))

    second_cells = get_cells("A", "G", 5, 8)
    second_avg = get_cells_avg_color(img, second_cells)
    print("Second color average: blue {:0.2f}, green {:0.2f}, red {:0.2f}".format(*second_avg))

if __name__ == "__main__":
    if len(sys.argv) == 2:
        main(sys.argv[1])
    else:
        print("Usage: python {} plate.jpg".format(__name__))
</code>```

Body:
We are working on a code that looks at a 96-well plate. We have the centers coordinates of each well. We then created a for loop that would allow us get the BGR value of each well. However, we need to somehow organize each column and average those values. I believe that we are getting an error from the first loop. With this one, it seems like the function only goes through the first loop and not the second one. When I run it, I get 3 values (assuming to be bgr values) and then proceeds to push out the averages. It also seems to repeat some average values. Any suggestions to what I can change, or errors at first-look. I will provide the image and legend below.

Links to images are:
http://imgur.com/Eb87ZxW (the image was scaled, so the coordinates may not work with the uploaded image)
http://imgur.com/P4tPPXX

import cv2, numpy as np, sys

#filename will be taken from the command line and process as the image variable
#filename= sys.argv([1])
img = cv2.imread('greenandblueplate.jpg')

#centroids
wells = [img[110,97], img[184,97], img[254,97], img[324,97], img[396,96], img[466,97], #columnH 12-7
         img[537,96], img[607,97], img[680,96], img[750,97], img[820,96], img[891,97], #columnH 6-1
         img[110,165],img[184,165],img[254,165],img[324,165],img[396,165],img[466,165], #columnG 12-7
         img[537,165],img[607,165],img[680,165],img[750,166],img[820,165],img[891,165], #columnG 6-1
         img[110,235],img[184,235],img[254,235],img[324,235],img[396,235],img[466,235], #columnF 12-7
         img[537,235],img[607,235],img[680,235],img[750,235],img[820,235],img[891,235], #columnF 6-1
         img[110,305],img[184,305],img[254,305],img[324,305],img[396,305],img[466,305], #columnE 12-7
         img[537,305],img[607,305],img[680,305],img[750,305],img[820,305],img[891,305], #columnE 6-1
         img[110,373],img[184,373],img[254,373],img[324,373],img[396,373],img[466,373], #columnD 12-7
         img[537,373],img[607,373],img[680,373],img[750,372],img[820,373],img[891,373], #columnD 6-1
         img[110,442],img[184,442],img[254,442],img[324,442],img[396,442],img[466,442], #columnC 12-7
         img[537,442],img[607,442],img[680,442],img[750,443],img[820,442],img[891,442], #columnC 6-1
         img[109,511],img[184,511],img[254,511],img[324,511],img[396,511],img[466,511], #columnB 12-7
         img[537,512],img[607,512],img[680,511],img[750,511],img[820,511],img[891,511], #columnB 6-1
         img[109,582],img[184,582],img[254,582],img[324,581],img[396,582],img[466,582], #columnA 12-7
         img[537,581],img[607,582],img[680,582],img[750,581],img[820,582],img[891,582]] #columnA 6-1

bAvgFilledWells = []
gAvgFilledWells = []
rAvgFilledWells = []

#filtering out the centroids that are not needed
#and getting the bgr values for the first color on the plate
for center in wells:
    if center[1] > 124:
        if center[0] < 360:
            b = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 0]
            g = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 1]
            r = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 2]
            bAvg = np.mean(b)
            gAvg = np.mean(g)
            rAvg = np.mean(r)

            bAvgFilledWells.append(bAvg)
            gAvgFilledWells.append(gAvg)
            rAvgFilledWells.append(rAvg)
            print(center)
            print("For the first color, average value for blue is:", bAvg)
            print("For the first color, average value for green is:", gAvg)
            print("For the first color, average value for red is:", rAvg)

bAvgFilledWells2 = []
gAvgFilledWells2 = []
rAvgFilledWells2 = []

#filtering out the centroids that are not needed
#and getting the bgr values for the second color on the plate
for center in wells:
    if center[1] > 124:
        if center[0] > 360 and center[0] < 642:
            b2 = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 0]
            g2 = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 1]
            r2 = img[center[0]-4: center[0]+5, center[1]-4: center[1]+5, 2]
            bAvg2 = np.mean(b2)
            gAvg2 = np.mean(g2)
            rAvg2 = np.mean(r2)

            print(center)
            print("For the second color, average value for blue is:", bAvg2)
            print("For the second color, average value for green is:", gAvg2)
            print("For the second color, average value for blue is:", rAvg2)
            bAvgFilledWells2.append(bAvg2)
            gAvgFilledWells2.append(gAvg2)
            rAvgFilledWells2.append(rAvg2)

Body:
Here's how I would rewrite your code:

import cv2
from itertools import product
import numpy as np
import sys

# image coordinates
ROWS = (891, 820, 750, 680, 607, 537, 466, 396, 324, 254, 184, 110)   # rows 1..12
COLS = (582, 511, 442, 373, 305, 235, 165, 97)                        # cols A..H

def get_rect_avg_color(img, x, y, w=8, h=8):
    """
    Return the BGR average color of a rectangular area of the image
      centered on (x,y) with width w and height h
    """
    half_w = w // 2
    half_h = h // 2
    # extract the rectangular area
    rect = img[x - half_w: x + (w - half_w) + 1, y - half_h: y + (h - half_h) + 1]
    # average each channel independantly
    avg_col = rect.mean(axis=(0,1))
    return avg_col    # returns [avg_b, avg_g, avg_r]

def get_cells_avg_color(img, cells):
    """
    Return the BGR average color of a list of cells
    """
    cell_colors = np.vstack(get_rect_avg_color(img, *cell) for cell in cells)
    return cell_colors.mean(axis=0)    # returns [avg_b, avg_g, avg_r]

def get_cells(col_from, col_to, row_from, row_to):
    """
    Return a list of all cells in a rectangular block

    col_from, col_to  in "A".."H"
    row_from, row_to  in 1..12

    col_to and row_to are inclusive
    """
    col_from  = ord(col_from.upper()) - ord("A")
    col_to    = ord(col_to  .upper()) - ord("A")
    col_from, col_to = min(col_from, col_to), max(col_from, col_to)
    row_from -= 1
    row_to   -= 1
    row_from, row_to = min(row_from, row_to), max(row_from, row_to)
    return product(ROWS[row_from:row_to + 1], COLS[col_from:col_to + 1])

def main(img_fname):
    img = cv2.imread(img_fname)

    first_cells = get_cells("A", "G", 9, 12)
    first_avg = get_cells_avg_color(img, first_cells)
    print("First color average: blue {:0.2f}, green {:0.2f}, red {:0.2f}".format(*first_avg))

    second_cells = get_cells("A", "G", 5, 8)
    second_avg = get_cells_avg_color(img, second_cells)
    print("Second color average: blue {:0.2f}, green {:0.2f}, red {:0.2f}".format(*second_avg))

if __name__ == "__main__":
    if len(sys.argv) == 2:
        main(sys.argv[1])
    else:
        print("Usage: python {} plate.jpg".format(__name__))