1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
Description: Make sure generated playlist have predictable ordering.
Sort playlist on file size, largest first.
Author: Petter Reinholdtsen <pere@debian.org>
Forwarded: https://github.com/johang/vlc-bittorrent/issues/9
Reviewed-By: Petter Reinholdtsen <pere@debian.org>
Last-Update: 2018-10-07
Index: vlc-plugin-bittorrent-salsa/src/metadata.cpp
===================================================================
--- vlc-plugin-bittorrent-salsa.orig/src/metadata.cpp 2018-10-07 09:31:45.466709941 +0200
+++ vlc-plugin-bittorrent-salsa/src/metadata.cpp 2018-10-07 09:32:17.415179698 +0200
@@ -103,6 +103,18 @@
return *buf_sz > 0;
}
+// Functor to compare by the Mth element, from
+// https://stackoverflow.com/questions/23030267/custom-sorting-a-vector-of-tuples#23030402
+template<int M, template<typename> class F = std::greater>
+struct TupleCompare
+{
+ template<typename T>
+ bool operator()(T const &t1, T const &t2)
+ {
+ return F<typename std::tuple_element<M, T>::type>()(std::get<M>(t1), std::get<M>(t2));
+ }
+};
+
static bool
build_playlist(stream_t *p_demux, input_item_node_t *p_subitems, char *buf,
size_t buf_sz)
@@ -137,27 +149,30 @@
// Bencode metadata and dump it to file
bencode(std::ostream_iterator<char>(out), t.generate());
- std::vector<std::string> files;
+ std::vector< std::tuple<boost::int64_t, std::string> > files;
for (int i = 0; i < metadata.num_files(); i++) {
- files.push_back(metadata.file_at(i).path);
+ files.push_back(std::tuple<boost::int64_t,
+ std::string>(metadata.file_at(i).size,
+ metadata.file_at(i).path));
}
+ std::sort(files.begin(), files.end(), TupleCompare<0>());
input_item_t *p_current_input = input_GetItem(p_demux->p_input);
// How many characters to remove from the beginning of each title
size_t offset = (files.size() > 1) ? metadata.name().length() : 0;
- for (std::vector<std::string>::iterator i = files.begin();
- i != files.end(); ++i) {
+ for (std::vector< std::tuple<boost::int64_t, std::string> >::iterator i = files.begin();
+ i != files.end(); ++i) {
std::string item_path;
item_path += "bittorrent://";
item_path += path;
item_path += "?";
- item_path += *i;
+ item_path += std::get<1>(*i);
- std::string item_title((*i).substr(offset));
+ std::string item_title((std::get<1>(*i)).substr(offset));
// Create an item for each file
input_item_t *p_input = input_item_New(
|