Пример #1
0
  public boolean prepNextSong() {
    mp.reset();

    if (currentPlaylist.size() > 0) {
      currentTrack = currentPlaylist.get(globalTrackNo++);

      MySongManager.rebuildStats(this, currentTrack.getLocal_id());

      try {
        mp.setDataSource(currentTrack.getPath());
        mp.prepare();
      } catch (IOException e) {
        e.printStackTrace();
        return false;
      }

      int i = Math.max(currentPlaylist.size() - 5, globalTrackNo);

      if (currentPlaylist.size() - 5 <= globalTrackNo) {
        // TODO async
        currentPlaylist.addAll(generateNewTracks(sessionType));
      }
      return true;
    } else {
      return false;
    }
  }
Пример #2
0
  private void checkIfRegisterAsSkip() {
    if (currentTrack != null) {
      long millis = System.currentTimeMillis() - mStartTime;
      accumulatedPlaytimeForThisTrack += millis;

      if (accumulatedPlaytimeForThisTrack > currentTrack.getDuration() / 2) {
        // dun consider as skip, just "next"
        createTrackStats(currentTrack.getLocal_id(), TrackStats.SONG_HALF_PLAYED);
      } else {
        // its a skip, the guy dun like this song1
        createTrackStats(currentTrack.getLocal_id(), TrackStats.SONG_SKIPPED);
      }
    }
  }
Пример #3
0
  public void showNotification() {
    if (currentTrack != null) {
      mNotificationBuilder =
          new Notification.Builder(this)
              .setSmallIcon(android.R.drawable.sym_def_app_icon)
              .setContentTitle(currentTrack.getTitle())
              .setContentText(currentTrack.getArtist())
              .setContentIntent(activityIntent)
              .addAction(android.R.drawable.ic_media_play, "PlayPause", playPausePendingIntent)
              .addAction(android.R.drawable.ic_media_next, "Next", nextPendingIntent)
              .addAction(0, "Dismiss", dismissPendingIntent);

      mNotification = mNotificationBuilder.build();
      mNotification.flags = Notification.FLAG_ONGOING_EVENT;

      mNotificationManager.notify(NOTIFICATION_ID, mNotification);
    }
  }
Пример #4
0
  private List<Track> getUnderratedPlaylist(List<Track> tempTrackList) {
    Log.d(TAG, "getUnderratedPlaylist()");
    List<Track> tempList = new ArrayList<Track>();

    /**
     * referring to how many times does a song need to be played/selected before it is not a rookie
     * TODO XZ: in future, this should be a relative number such as top played song is at 100
     * completeCount hence an underrated song would be, say maxCount * 0.4?
     */
    int rookieThreshold = 10;

    if (!tempTrackList.isEmpty()) {
      Collections.shuffle(tempTrackList);

      for (Track t : tempTrackList) {

        int completedCount = t.getCompletedCount();
        int skippedCount = t.getSkippedCount();
        int selectedCount = t.getSelectedCount();
        int likedCount = t.getLikedCount();
        int dislikedCount = t.getDislikedCount();

        if (completedCount + selectedCount < rookieThreshold) {
          if (selectedCount > 2) {
            if (skippedCount <= completedCount) {
              tempList.add(t);
            }
          } else {
            if (completedCount > 2) {
              tempList.add(t);
            } else {
              if (likedCount > dislikedCount) {
                tempList.add(t);
              }
            }
          }
        }

        if (tempList.size() == 10) {
          break;
        }
      }
    }

    Log.d(TAG, "tempList.size():" + tempList.size());

    return tempList;
  }
Пример #5
0
  public static void updateLibrary(Context context, boolean rebuildStats) {
    Log.d(TAG, "updateLibrary() start");

    Realm realm = Realm.getInstance(Migration.getConfig(context));

    realm.beginTransaction();
    RealmResults<Track> res = realm.where(Track.class).findAll();
    for (int x = 0; x < res.size(); x++) {
      res.get(x).setIsAvailable(false);
    }
    realm.commitTransaction();

    String where = MediaStore.Audio.Media.IS_MUSIC + " = 1";
    String[] selectionArgs = null;
    String orderBy = MediaStore.Audio.Media.DEFAULT_SORT_ORDER;

    ContentResolver contentResolver = context.getContentResolver();

    Cursor[] cursors = new Cursor[2];
    cursors[0] =
        contentResolver.query(
            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            TRACK_COLUMNS,
            where,
            selectionArgs,
            orderBy);

    cursors[1] =
        contentResolver.query(
            MediaStore.Audio.Media.INTERNAL_CONTENT_URI,
            TRACK_COLUMNS,
            where,
            selectionArgs,
            orderBy);

    Cursor cursor = new MergeCursor(cursors);

    int idColumn = cursor.getColumnIndex(MediaStore.Audio.Media._ID);
    int displayNameColumn = cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME);
    int titleColumn = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
    int titleKeyColumn = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE_KEY);
    int durationColumn = cursor.getColumnIndex(MediaStore.Audio.Media.DURATION);
    int trackColumn = cursor.getColumnIndex(MediaStore.Audio.Media.TRACK);
    int artistColumn = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
    // int dateAddedColumn 	= cursor.getColumnIndex(MediaStore.Audio.Media.DATE_ADDED);
    int dataColumn = cursor.getColumnIndex(MediaStore.Audio.Media.DATA);
    int albumColumn = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM);
    int albumIdColumn = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID);
    int albumKeyColumn = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_KEY);

    realm.beginTransaction();

    while (cursor.moveToNext()) {
      int minimumDurationToConsiderAsSong = 61500;

      Track track = null;

      String local_id =
          Track.getLocalId(
              cursor.getString(titleColumn),
              cursor.getString(artistColumn),
              cursor.getString(albumColumn));

      Track res2 = realm.where(Track.class).equalTo("local_id", local_id).findFirst();

      if (res2 != null) {
        if (cursor.getInt(durationColumn) < minimumDurationToConsiderAsSong) {
          res2.removeFromRealm();
        } else {
          track = res2;
          track.setIsAvailable(true);

          if (!track.isHidden()) {
            if (rebuildStats) {
              rebuildStats(context, track.getLocal_id());
            }
          }
        }
      } else {
        if (cursor.getInt(durationColumn) > minimumDurationToConsiderAsSong) {
          //                    Log.d(TAG, "hi6 - means its a new record");
          //                    Log.d(TAG, "cursor.getString(titleColumn): " +
          // cursor.getString(titleColumn));
          //                    Log.d(TAG, "cursor.getString(artistColumn): " +
          // cursor.getString(artistColumn));
          //                    Log.d(TAG, "cursor.getString(albumColumn): " +
          // cursor.getString(albumColumn));

          track =
              new Track(
                  cursor.getString(titleColumn),
                  cursor.getString(artistColumn),
                  cursor.getString(albumColumn),
                  cursor.getString(dataColumn));

          track.setId(cursor.getLong(idColumn));
          track.setDisplayName(cursor.getString(displayNameColumn));
          track.setTitleKey(cursor.getString(titleKeyColumn));
          track.setDuration(cursor.getInt(durationColumn));
          track.setTrackNo(cursor.getInt(trackColumn));
          track.setAlbumId(cursor.getString(albumIdColumn));
          track.setAlbumKey(cursor.getString(albumKeyColumn));

          track = realm.copyToRealm(track);
        }
      }

      if (track != null) {
        track.setPath(cursor.getString(dataColumn));
      }
    }
    realm.commitTransaction();

    cursor.close();
    Log.d(TAG, "updateLibrary() end");
  }
Пример #6
0
  public static void rebuildStats(Context context, String localId) {
    Realm realm = Realm.getInstance(Migration.getConfig(context));

    RealmResults<TrackStats> statsRes =
        realm.where(TrackStats.class).equalTo("local_id", localId).findAll();

    if (!statsRes.isEmpty()) {
      /*
      Log.d(TAG, "hi5");
      Log.d(TAG, "==================");
      Log.d(TAG, "track.getTitle(): " + track.getTitle());
      Log.d(TAG, "track.getCompletedCount(): " + track.getCompletedCount());
      Log.d(TAG, "track.getSkippedCount(): " + track.getSkippedCount());
      Log.d(TAG, "track.getLikedCount(): " + track.getLikedCount());
      Log.d(TAG, "track.getDislikedCount(): " + track.getDislikedCount());

      res.where().equalTo("type", TrackStats.SONG_SELECTED) //TODO not implemented yet
       */

      int completedCount = 0;
      int skippedCount = 0;
      int likedCount = 0;
      int dislikedCount = 0;
      int halfPlayedCount = 0;
      int selectedCount = 0;

      for (TrackStats ts : statsRes) {
        switch (ts.getType()) {
          case TrackStats.SONG_COMPLETED:
            completedCount++;
            break;
          case TrackStats.SONG_HALF_PLAYED:
            halfPlayedCount++;
            break;
          case TrackStats.SONG_SELECTED:
            selectedCount++;
            break;
          case TrackStats.SONG_SKIPPED:
            skippedCount++;
            break;
          case TrackStats.SONG_LIKED:
            likedCount++;
            break;
          case TrackStats.SONG_DISLIKED:
            dislikedCount++;
            break;
        }
      }

      Track track = realm.where(Track.class).equalTo("local_id", localId).findFirst();

      realm.beginTransaction();

      track.setCompletedCount(completedCount);
      track.setHalfPlayedCount(halfPlayedCount);
      track.setSelectedCount(selectedCount);

      track.setSkippedCount(skippedCount);

      track.setLikedCount(likedCount);
      track.setDislikedCount(dislikedCount);

      track.setStatsUpdatedAt(DateTime.now(Calendar.getInstance().getTimeZone()).toString());

      realm.commitTransaction();
    }
  }
Пример #7
0
  private List<Track> getGeneralPlaylist(List<Track> tempTrackList) {
    List<Track> tempList = new ArrayList<Track>();

    if (tempTrackList != null) {
      Collections.sort(
          tempTrackList,
          new Comparator<Track>() {
            @Override
            public int compare(Track left, Track right) {
              return (left.getCompletedCount() + left.getSkippedCount())
                  - (right.getCompletedCount() + right.getSkippedCount());
            }
          });
      Iterator<Track> iter = tempTrackList.iterator();

      while (iter.hasNext()) {
        Track newTrack = iter.next();
        if (newTrack.getSkippedCount() + newTrack.getCompletedCount() > 3) {
          break;
        }

        if (Math.random() > 0.2) {
          tempList.add(newTrack);
          iter.remove();

          if (tempTrackList.size() > 3) {
            break;
          }
        }
      }

      Collections.shuffle(tempTrackList);

      for (Track t : tempTrackList) {
        // Log.d(TAG, "t.getTitle(): " + t.getTitle());

        int completedCount = t.getCompletedCount();
        int skippedCount = t.getSkippedCount();
        // res.where().equalTo("type", TrackStats.SONG_SELECTED) //TODO not implemented yet
        int likedCount = t.getLikedCount();
        int dislikedCount = t.getDislikedCount();

        /**
         * TODO need to make the ratio more representative of the respective counts i.e. if i
         * completed the song once, it should only give like 0.6 but if i completed the song 100
         * times, it should give like 0.9?
         */
        int comMinusSkip = completedCount - skippedCount;
        double cmsRatio = 0;
        if (comMinusSkip > 0) {
          cmsRatio = 0.9;
        } else {
          if (comMinusSkip == 0) {
            cmsRatio = 0.5;
          } else {
            cmsRatio = 0.1;
          }
        }

        // TODO similarly as above, this algo needs rework in future
        int likeMinusDislike = likedCount - dislikedCount;
        double lmdRatio = 0;
        if (likeMinusDislike > 0) {
          lmdRatio = 0.9;
        } else {
          if (likeMinusDislike == 0) {
            lmdRatio = 0.5;
          } else {
            lmdRatio = 0.1;
          }
        }

        // XZ: it should add up to 100 in total
        final double chanceContributionWeightage = 50;
        final double completedVsSkippedContributionWeightage = 20;
        final double likeDislikeContributionWeightage = 30;

        double chanceContribution = chanceContributionWeightage * Math.random();
        double completedVsSkippedContribution = completedVsSkippedContributionWeightage * cmsRatio;
        double likeDislikeContribution = likeDislikeContributionWeightage * lmdRatio;

        // double selectedContribution    = 20; //TODO *WIP*
        // double freshnessContribution    = 20; //TODO *WIP*

        double points =
            chanceContribution + completedVsSkippedContribution + likeDislikeContribution;

        if (points > PASSING_GRADE) {
          tempList.add(t);
        }

        if (tempList.size() == 10) {
          break;
        }
      }
    }
    return tempList;
  }