Skip to content

Commit 2b3f6d2

Browse files
authored
Merge pull request #239 from tobexyz/issue230
Issue230
2 parents 4058b9b + f7015af commit 2b3f6d2

2 files changed

Lines changed: 223 additions & 39 deletions

File tree

yaacc/src/main/java/de/yaacc/upnp/server/contentdirectory/SafFolderBrowser.java

Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,18 @@
1919
package de.yaacc.upnp.server.contentdirectory;
2020

2121
import android.content.Context;
22-
import android.content.SharedPreferences;
23-
import android.media.MediaMetadataRetriever;
2422
import android.net.Uri;
2523
import android.provider.DocumentsContract;
2624
import android.util.Base64;
2725

2826
import androidx.documentfile.provider.DocumentFile;
29-
import androidx.preference.PreferenceManager;
3027

3128
import org.fourthline.cling.support.model.DIDLObject;
32-
import org.fourthline.cling.support.model.Protocol;
3329
import org.fourthline.cling.support.model.ProtocolInfo;
34-
import org.fourthline.cling.support.model.Res;
3530
import org.fourthline.cling.support.model.SortCriterion;
3631
import org.fourthline.cling.support.model.container.Container;
3732
import org.fourthline.cling.support.model.container.StorageFolder;
38-
import org.fourthline.cling.support.model.item.AudioItem;
39-
import org.fourthline.cling.support.model.item.ImageItem;
4033
import org.fourthline.cling.support.model.item.Item;
41-
import org.fourthline.cling.support.model.item.VideoItem;
4234
import org.seamless.util.MimeType;
4335

4436
import java.util.ArrayList;
@@ -51,7 +43,6 @@
5143
import de.yaacc.upnp.model.YaaccRes;
5244
import de.yaacc.util.SAFCacheManager;
5345
import de.yaacc.util.SAFMetadata;
54-
import de.yaacc.util.FormatHelper;
5546
import de.yaacc.util.YaaccLogger;
5647

5748
/**
@@ -64,7 +55,7 @@ public class SafFolderBrowser extends ContentBrowser {
6455
public SafFolderBrowser(Context context) {
6556
super(context);
6657
}
67-
58+
6859
@Override
6960
public DIDLObject browseMeta(YaaccContentDirectory contentDirectory, String myId, long firstResult, long maxResults, SortCriterion[] orderby) {
7061
if (myId.equals(ContentDirectoryIDs.SAF_FOLDER.getId())) {
@@ -151,12 +142,12 @@ public List<Container> browseContainer(YaaccContentDirectory contentDirectory, S
151142
YaaccLogger.d(getClass().getName(), "Browsing subfolder with ID: " + myId);
152143
String shortId = myId.substring(ContentDirectoryIDs.SAF_PREFIX.getId().length());
153144
String path = SAFCacheManager.getInstance(getContext()).getUriForShortId(shortId);
154-
145+
155146
if (path == null) {
156147
YaaccLogger.e(getClass().getName(), "Short ID not found: " + shortId);
157148
return result;
158149
}
159-
150+
160151
YaaccLogger.d(getClass().getName(), "Resolved path from shortId " + shortId + ": " + path);
161152

162153
Uri uri = Uri.parse(path);
@@ -176,11 +167,11 @@ public List<Container> browseContainer(YaaccContentDirectory contentDirectory, S
176167
long listStart = System.currentTimeMillis();
177168
DocumentFile[] files = root.listFiles();
178169
YaaccLogger.d(getClass().getName(), "listFiles() took " + (System.currentTimeMillis() - listStart) + "ms, found " + files.length + " items");
179-
170+
180171
int start = (int) Math.max(0, firstResult);
181172
int end = (int) Math.min(files.length, start + maxResults);
182173
YaaccLogger.d(getClass().getName(), "Pagination: start=" + start + ", end=" + end + ", total=" + files.length);
183-
174+
184175
for (int i = start; i < end; i++) {
185176
long itemStart = System.currentTimeMillis();
186177
DocumentFile file = files[i];
@@ -238,7 +229,12 @@ public List<Item> browseItem(YaaccContentDirectory contentDirectory, String myId
238229
DocumentFile file = DocumentFile.fromSingleUri(getContext(), Uri.parse(path));
239230
if (file != null && !file.isDirectory()) {
240231
Item item = createItem(contentDirectory, path, file, myId, !file.canRead());
241-
if (item != null) result.add(item);
232+
if (item != null) {
233+
result.add(item);
234+
YaaccLogger.d(getClass().getName(), "✓ Added to result: Item[" + (result.size() - 1) + "] " + (file.getName() != null ? file.getName() : "unknown"));
235+
} else {
236+
YaaccLogger.d(getClass().getName(), "✗ Skipped (null item): " + (file.getName() != null ? file.getName() : "unknown"));
237+
}
242238
YaaccLogger.d(getClass().getName(), "Item[" + i + "] " + (file.getName() != null ? file.getName() : "unknown") + " (took " + (System.currentTimeMillis() - itemStart) + "ms)");
243239
}
244240
}
@@ -249,26 +245,26 @@ public List<Item> browseItem(YaaccContentDirectory contentDirectory, String myId
249245
YaaccLogger.d(getClass().getName(), "Browsing subfolder items for: " + myId);
250246
String shortId = myId.substring(ContentDirectoryIDs.SAF_PREFIX.getId().length());
251247
String path = SAFCacheManager.getInstance(getContext()).getUriForShortId(shortId);
252-
248+
253249
if (path == null) {
254250
YaaccLogger.e(getClass().getName(), "Short ID not found: " + shortId);
255251
return result;
256252
}
257-
253+
258254
long treeStart = System.currentTimeMillis();
259255
DocumentFile root = DocumentFile.fromTreeUri(getContext(), Uri.parse(path));
260256
YaaccLogger.d(getClass().getName(), "Tree URI resolved in " + (System.currentTimeMillis() - treeStart) + "ms");
261-
257+
262258
if (root != null && root.isDirectory()) {
263259
if (root.canRead()) {
264260
long listStart = System.currentTimeMillis();
265261
DocumentFile[] files = root.listFiles();
266262
YaaccLogger.d(getClass().getName(), "listFiles() took " + (System.currentTimeMillis() - listStart) + "ms, found " + files.length + " items");
267-
263+
268264
int start = (int) Math.max(0, firstResult);
269265
int end = (int) Math.min(files.length, start + maxResults);
270266
YaaccLogger.d(getClass().getName(), "Pagination: start=" + start + ", end=" + end + ", total=" + files.length);
271-
267+
272268
for (int i = start; i < end; i++) {
273269
long itemStart = System.currentTimeMillis();
274270
DocumentFile file = files[i];
@@ -296,61 +292,80 @@ public List<Item> browseItem(YaaccContentDirectory contentDirectory, String myId
296292
private Item createItem(YaaccContentDirectory contentDirectory, String path, DocumentFile file, String parentId, boolean restricted) {
297293
long createStart = System.currentTimeMillis();
298294
String fileName = file.getName() != null ? file.getName() : "unknown";
299-
295+
300296
if (file.getName() != null && file.getName().endsWith("m3u")) {
301297
return null;
302298
}
303-
299+
304300
// Get all metadata from cache (duration, MIME type, short ID)
305301
SAFMetadata metadata = SAFCacheManager.getInstance(getContext()).getMetadata(file);
306-
if (metadata == null || metadata.mimeType == null) {
302+
if (metadata == null) {
307303
return null;
308304
}
309305

310-
MimeType mimeType = MimeType.valueOf(metadata.mimeType);
306+
// If MIME type is null or invalid, try to guess from filename
307+
String mimeTypeStr = metadata.mimeType;
308+
if (mimeTypeStr == null || mimeTypeStr.equals("null") || !mimeTypeStr.contains("/")) {
309+
mimeTypeStr = SAFCacheManager.getInstance(getContext()).guessMimeTypeFromExtension(file.getName());
310+
if (mimeTypeStr == null) {
311+
return null; // Still couldn't determine MIME type
312+
}
313+
}
314+
315+
MimeType mimeType = MimeType.valueOf(mimeTypeStr);
311316
String mimeTypeMain = mimeType.getType();
312-
317+
313318
String id = ContentDirectoryIDs.SAF_PREFIX.getId() + metadata.shortId;
314-
String title = file.getName() != null ? file.getName() : path;
319+
String title = file.getName() != null ? file.getName() : extractFilenameFromUri(path);
320+
if (file.getName() == null) {
321+
YaaccLogger.d(getClass().getName(), "file.getName() is null for URI: " + file.getUri());
322+
}
323+
315324
if (restricted) {
316325
title = "[X] " + title;
317326
}
318-
327+
319328
// Use shortId in URI instead of Base64-encoded path
320329
String uri = getUriString(contentDirectory, id, mimeType, metadata.shortId);
321330
YaaccLogger.d(getClass().getName(), "Generated URI for " + title + ": " + uri + " (shortId=" + metadata.shortId + ")");
322-
331+
323332
long protocolStart = System.currentTimeMillis();
324333
ProtocolInfo protocolInfo = getProtocolInfo(mimeType);
325334
long protocolTime = System.currentTimeMillis() - protocolStart;
326-
335+
327336
String duration = null;
328337
if (mimeTypeMain.equals("audio") && !restricted) {
329338
duration = metadata.duration;
330339
}
331-
340+
332341
// Create lightweight YaaccRes (no Cling overhead)
333342
YaaccRes yaaccRes = new YaaccRes(protocolInfo, metadata.fileSize, duration, null, uri);
334-
343+
335344
// Create lightweight YaaccItem (no Cling Property overhead)
336345
long itemStart = System.currentTimeMillis();
337-
String clazz = mimeTypeMain.equals("audio") ? "object.item.audioItem"
338-
: mimeTypeMain.equals("video") ? "object.item.videoItem"
339-
: "object.item.imageItem";
346+
String clazz = mimeTypeMain.equals("audio") ? "object.item.audioItem"
347+
: mimeTypeMain.equals("video") ? "object.item.videoItem"
348+
: "object.item.imageItem";
340349
YaaccItem yaaccItem = new YaaccItem(id, parentId, title, "yaacc", restricted, clazz);
341350
yaaccItem.addResource(yaaccRes);
342351
long itemTime = System.currentTimeMillis() - itemStart;
343-
352+
344353
// Convert to Cling Item only at the end (for UPnP serialization)
345354
long convertStart = System.currentTimeMillis();
346355
Item item = yaaccItem.toClingItem();
347356
long convertTime = System.currentTimeMillis() - convertStart;
348-
357+
349358
long totalTime = System.currentTimeMillis() - createStart;
350359
YaaccLogger.d(getClass().getName(), "Item[?] " + fileName + " - protocolInfo=" + protocolTime + "ms, YaaccItem=" + itemTime + "ms, convert=" + convertTime + "ms, total=" + totalTime + "ms");
351360
return item;
352361
}
353362

363+
private String extractFilenameFromUri(String path) {
364+
if (path == null) return "unknown";
365+
int lastSlash = path.lastIndexOf('/');
366+
return lastSlash >= 0 ? path.substring(lastSlash + 1) : path;
367+
}
368+
354369
/*
355370
private void loadDurationAsync(DocumentFile file, Item item, Res res) {
356371

0 commit comments

Comments
 (0)