From 966850d9b75a74c036fbf07fa01751cb32d35712 Mon Sep 17 00:00:00 2001
From: Markus Himmel <markus@himmel-villmar.de>
Date: Thu, 7 Jan 2016 12:06:20 +0100
Subject: [PATCH] MediaPlayer: Show individual track length in playlist window
---
src/apps/mediaplayer/playlist/FilePlaylistItem.cpp | 13 +++++++
src/apps/mediaplayer/playlist/FilePlaylistItem.h | 3 ++
src/apps/mediaplayer/playlist/PlaylistItem.cpp | 35 +++++++++++++++++
src/apps/mediaplayer/playlist/PlaylistItem.h | 3 ++
src/apps/mediaplayer/playlist/PlaylistListView.cpp | 16 +++++++-
src/apps/mediaplayer/playlist/PlaylistWindow.cpp | 45 +---------------------
src/apps/mediaplayer/playlist/PlaylistWindow.h | 1 -
7 files changed, 70 insertions(+), 46 deletions(-)
diff --git a/src/apps/mediaplayer/playlist/FilePlaylistItem.cpp b/src/apps/mediaplayer/playlist/FilePlaylistItem.cpp
index 9279fe1..976cff4 100644
a
|
b
|
|
13 | 13 | #include <File.h> |
14 | 14 | #include <FindDirectory.h> |
15 | 15 | #include <MediaFile.h> |
| 16 | #include <MediaTrack.h> |
16 | 17 | #include <Path.h> |
17 | 18 | #include <TranslationUtils.h> |
18 | 19 | |
… |
… |
FilePlaylistItem::ImageRef() const
|
398 | 399 | } |
399 | 400 | |
400 | 401 | |
| 402 | bigtime_t |
| 403 | FilePlaylistItem::_CalculateDuration() const |
| 404 | { |
| 405 | BMediaFile mediaFile(&Ref()); |
| 406 | |
| 407 | if (mediaFile.InitCheck() != B_OK || mediaFile.CountTracks() < 1) |
| 408 | return 0; |
| 409 | |
| 410 | return mediaFile.TrackAt(0)->Duration(); |
| 411 | } |
| 412 | |
| 413 | |
401 | 414 | status_t |
402 | 415 | FilePlaylistItem::_SetAttribute(const char* attrName, type_code type, |
403 | 416 | const void* data, size_t size) |
diff --git a/src/apps/mediaplayer/playlist/FilePlaylistItem.h b/src/apps/mediaplayer/playlist/FilePlaylistItem.h
index fb72f9e..5ca3e43 100644
a
|
b
|
public:
|
61 | 61 | status_t AddImageRef(const entry_ref& ref); |
62 | 62 | const entry_ref& ImageRef() const; |
63 | 63 | |
| 64 | protected: |
| 65 | virtual bigtime_t _CalculateDuration() const; |
| 66 | |
64 | 67 | private: |
65 | 68 | status_t _SetAttribute(const char* attrName, |
66 | 69 | type_code type, const void* data, |
diff --git a/src/apps/mediaplayer/playlist/PlaylistItem.cpp b/src/apps/mediaplayer/playlist/PlaylistItem.cpp
index fde90a8..e3ec718 100644
a
|
b
|
|
10 | 10 | #include <Catalog.h> |
11 | 11 | #include <Locale.h> |
12 | 12 | |
| 13 | #include "AudioTrackSupplier.h" |
| 14 | #include "TrackSupplier.h" |
| 15 | #include "VideoTrackSupplier.h" |
13 | 16 | |
14 | 17 | #undef B_TRANSLATION_CONTEXT |
15 | 18 | #define B_TRANSLATION_CONTEXT "MediaPlayer-PlaylistItem" |
… |
… |
PlaylistItem::TrackNumber() const
|
107 | 110 | } |
108 | 111 | |
109 | 112 | |
| 113 | bigtime_t |
| 114 | PlaylistItem::Duration() |
| 115 | { |
| 116 | bigtime_t duration; |
| 117 | if (GetAttribute(ATTR_INT64_DURATION, duration) != B_OK) { |
| 118 | duration = this->_CalculateDuration(); |
| 119 | SetAttribute(ATTR_INT64_DURATION, duration); |
| 120 | } |
| 121 | |
| 122 | return duration; |
| 123 | } |
| 124 | |
| 125 | |
110 | 126 | void |
111 | 127 | PlaylistItem::SetPlaybackFailed() |
112 | 128 | { |
… |
… |
PlaylistItem::_NotifyListeners() const
|
143 | 159 | } |
144 | 160 | } |
145 | 161 | |
| 162 | |
| 163 | bigtime_t PlaylistItem::_CalculateDuration() const |
| 164 | { |
| 165 | // To be overridden in subclasses with more efficient methods |
| 166 | TrackSupplier* supplier = CreateTrackSupplier(); |
| 167 | |
| 168 | AudioTrackSupplier* au = supplier->CreateAudioTrackForIndex(0); |
| 169 | VideoTrackSupplier* vi = supplier->CreateVideoTrackForIndex(0); |
| 170 | |
| 171 | bigtime_t duration = max_c(au == NULL ? 0 : au->Duration(), |
| 172 | vi == NULL ? 0 : vi->Duration()); |
| 173 | |
| 174 | delete vi; |
| 175 | delete au; |
| 176 | delete supplier; |
| 177 | |
| 178 | return duration; |
| 179 | } |
| 180 | |
diff --git a/src/apps/mediaplayer/playlist/PlaylistItem.h b/src/apps/mediaplayer/playlist/PlaylistItem.h
index 73de81a..5c7e94c 100644
a
|
b
|
public:
|
80 | 80 | |
81 | 81 | int32 TrackNumber() const; |
82 | 82 | |
| 83 | bigtime_t Duration(); |
| 84 | |
83 | 85 | // methods |
84 | 86 | virtual BString LocationURI() const = 0; |
85 | 87 | virtual status_t GetIcon(BBitmap* bitmap, |
… |
… |
public:
|
101 | 103 | |
102 | 104 | protected: |
103 | 105 | void _NotifyListeners() const; |
| 106 | virtual bigtime_t _CalculateDuration() const; |
104 | 107 | |
105 | 108 | private: |
106 | 109 | BList fListeners; |
diff --git a/src/apps/mediaplayer/playlist/PlaylistListView.cpp b/src/apps/mediaplayer/playlist/PlaylistListView.cpp
index d7dc9d8..005a7d5 100644
a
|
b
|
|
21 | 21 | #include "Controller.h" |
22 | 22 | #include "ControllerObserver.h" |
23 | 23 | #include "CopyPLItemsCommand.h" |
| 24 | #include "DurationToString.h" |
24 | 25 | #include "ImportPLItemsCommand.h" |
25 | 26 | #include "ListViews.h" |
26 | 27 | #include "MovePLItemsCommand.h" |
… |
… |
PlaylistListView::Item::Draw(BView* owner, BRect frame, const font_height& fh,
|
132 | 133 | float playbackMarkSize = playback_mark_size(fh); |
133 | 134 | float textOffset = text_offset(fh); |
134 | 135 | |
| 136 | char buffer[64]; |
| 137 | bigtime_t duration = fItem->Duration(); |
| 138 | duration /= 1000000; |
| 139 | duration_to_string(duration, buffer, sizeof(buffer)); |
| 140 | |
| 141 | BString truncatedDuration(buffer); |
| 142 | owner->TruncateString(&truncatedDuration, B_TRUNCATE_END, |
| 143 | frame.Width() - playbackMarkSize - textOffset); |
| 144 | float truncatedWidth = owner->StringWidth(truncatedDuration.String()); |
| 145 | owner->DrawString(truncatedDuration.String(), |
| 146 | BPoint(frame.right - truncatedWidth, |
| 147 | floorf(frame.top + frame.bottom + fh.ascent) / 2 - 1)); |
| 148 | |
135 | 149 | BString truncatedString(text); |
136 | 150 | owner->TruncateString(&truncatedString, B_TRUNCATE_MIDDLE, |
137 | | frame.Width() - playbackMarkSize - textOffset); |
| 151 | frame.Width() - playbackMarkSize - textOffset - truncatedWidth); |
138 | 152 | owner->DrawString(truncatedString.String(), |
139 | 153 | BPoint(frame.left + playbackMarkSize + textOffset, |
140 | 154 | floorf(frame.top + frame.bottom + fh.ascent) / 2 - 1)); |
diff --git a/src/apps/mediaplayer/playlist/PlaylistWindow.cpp b/src/apps/mediaplayer/playlist/PlaylistWindow.cpp
index c99e971..824a3cc 100644
a
|
b
|
|
22 | 22 | #include <File.h> |
23 | 23 | #include <FilePanel.h> |
24 | 24 | #include <Locale.h> |
25 | | #include <MediaFile.h> |
26 | | #include <MediaTrack.h> |
27 | 25 | #include <Menu.h> |
28 | 26 | #include <MenuBar.h> |
29 | 27 | #include <MenuItem.h> |
… |
… |
|
35 | 33 | #include <String.h> |
36 | 34 | #include <StringView.h> |
37 | 35 | |
38 | | #include "AudioTrackSupplier.h" |
39 | 36 | #include "CommandStack.h" |
40 | 37 | #include "DurationToString.h" |
41 | 38 | #include "MainApp.h" |
42 | 39 | #include "PlaylistListView.h" |
43 | 40 | #include "RWLocker.h" |
44 | | #include "TrackSupplier.h" |
45 | | #include "VideoTrackSupplier.h" |
46 | 41 | |
47 | 42 | #undef B_TRANSLATION_CONTEXT |
48 | 43 | #define B_TRANSLATION_CONTEXT "MediaPlayer-PlaylistWindow" |
… |
… |
void
|
548 | 543 | PlaylistWindow::DurationListener::_HandleItemAdded(PlaylistItem* item, |
549 | 544 | int32 index) |
550 | 545 | { |
551 | | bigtime_t duration = _DetermineItemDuration(item); |
| 546 | bigtime_t duration = item->Duration(); |
552 | 547 | fTotalDuration += duration; |
553 | 548 | fParent._UpdateTotalDuration(fTotalDuration); |
554 | 549 | fKnown.AddItem(new bigtime_t(duration), index); |
… |
… |
PlaylistWindow::DurationListener::_HandleItemRemoved(int32 index)
|
568 | 563 | delete deleted; |
569 | 564 | } |
570 | 565 | |
571 | | |
572 | | bigtime_t |
573 | | PlaylistWindow::DurationListener::_DetermineItemDuration(PlaylistItem* item) |
574 | | { |
575 | | bigtime_t duration; |
576 | | if (item->GetAttribute(PlaylistItem::ATTR_INT64_DURATION, duration) == B_OK) |
577 | | return duration; |
578 | | |
579 | | // We have to find out the duration ourselves |
580 | | if (FilePlaylistItem* file = dynamic_cast<FilePlaylistItem*>(item)) { |
581 | | // We are dealing with a file |
582 | | BMediaFile mediaFile(&file->Ref()); |
583 | | |
584 | | if (mediaFile.InitCheck() != B_OK || mediaFile.CountTracks() < 1) |
585 | | return 0; |
586 | | |
587 | | duration = mediaFile.TrackAt(0)->Duration(); |
588 | | } else { |
589 | | // Not a file, so fall back to the generic TrackSupplier solution |
590 | | TrackSupplier* supplier = item->CreateTrackSupplier(); |
591 | | |
592 | | AudioTrackSupplier* au = supplier->CreateAudioTrackForIndex(0); |
593 | | VideoTrackSupplier* vi = supplier->CreateVideoTrackForIndex(0); |
594 | | |
595 | | duration = max_c(au == NULL ? 0 : au->Duration(), |
596 | | vi == NULL ? 0 : vi->Duration()); |
597 | | |
598 | | delete vi; |
599 | | delete au; |
600 | | delete supplier; |
601 | | } |
602 | | |
603 | | // Store the duration for later use |
604 | | item->SetAttribute(PlaylistItem::ATTR_INT64_DURATION, duration); |
605 | | |
606 | | return duration; |
607 | | } |
608 | | |
diff --git a/src/apps/mediaplayer/playlist/PlaylistWindow.h b/src/apps/mediaplayer/playlist/PlaylistWindow.h
index 6b70e76..4ca65a7 100644
a
|
b
|
private:
|
70 | 70 | void _HandleItemAdded(PlaylistItem* item, |
71 | 71 | int32 index); |
72 | 72 | void _HandleItemRemoved(int32 index); |
73 | | bigtime_t _DetermineItemDuration(PlaylistItem* item); |
74 | 73 | |
75 | 74 | BObjectList<bigtime_t> |
76 | 75 | fKnown; |