diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h index a314f8cf729bf558339a65c27ed46fff23f50b85..5b35cf6ac92644604a399ccee75ae3ed97f3fd80 100644 --- a/include/vlc_playlist.h +++ b/include/vlc_playlist.h @@ -867,6 +867,18 @@ vlc_playlist_PlayAt(vlc_playlist_t *playlist, size_t index) VLC_API void vlc_playlist_Preparse(vlc_playlist_t *playlist, input_item_t *media); +/** + * Export the playlist to a file. + * + * \param filename the location where the exported file will be saved + * \param type the type of the playlist file to create (m3u, m3u8, xspf, ...) + * \return VLC_SUCCESS on success, another value on error + */ +// XXX use vlc_memstream instead of filename? +VLC_API int +vlc_playlist_Export(vlc_playlist_t *playlist, const char *filename, + const char *type); + /** @} */ # ifdef __cplusplus } diff --git a/include/vlc_playlist_export.h b/include/vlc_playlist_export.h new file mode 100644 index 0000000000000000000000000000000000000000..ffee11e621d764b6924eef97b6fd308734b22763 --- /dev/null +++ b/include/vlc_playlist_export.h @@ -0,0 +1,70 @@ +/***************************************************************************** + * vlc_playlist_export.h + ***************************************************************************** + * Copyright (C) 2019 VLC authors and VideoLAN + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#ifndef VLC_PLAYLIST_EXPORT_H +#define VLC_PLAYLIST_EXPORT_H + +#include <vlc_playlist.h> + +/** API for playlist export modules */ + +/** + * Opaque structure giving a read-only view of a playlist. + * + * The view is only valid until the playlist lock is released. + */ +struct vlc_playlist_view; + +/** + * Return the number of items in the view. + * + * The underlying playlist must be locked. + * + * \param view the playlist view + */ +VLC_API size_t +vlc_playlist_view_Count(struct vlc_playlist_view *view); + +/** + * Return the item at a given index. + * + * The index must be in range (less than vlc_playlist_view_Count()). + * + * The underlying playlist must be locked. + * + * \param view the playlist view + * \param index the index + * \return the playlist item + */ +VLC_API vlc_playlist_item_t * +vlc_playlist_view_Get(struct vlc_playlist_view *view, size_t index); + +/** + * Structure received by playlist export module. + */ +struct vlc_playlist_export +{ + struct vlc_common_members obj; + char *base_url; + FILE *file; + struct vlc_playlist_view *playlist_view; +}; + +#endif diff --git a/src/Makefile.am b/src/Makefile.am index da02159d3d17b1128b4c4c049072d4d225dbb4e5..e243f6473d4676a4fb2d9ebcbab7ca28c3ec861b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -80,6 +80,7 @@ pluginsinclude_HEADERS = \ ../include/vlc_playlist_legacy.h \ ../include/vlc_player.h \ ../include/vlc_playlist.h \ + ../include/vlc_playlist_export.h \ ../include/vlc_plugin.h \ ../include/vlc_probe.h \ ../include/vlc_rand.h \ @@ -237,6 +238,7 @@ libvlccore_la_SOURCES = \ playlist/content.h \ playlist/control.c \ playlist/control.h \ + playlist/export.c \ playlist/item.c \ playlist/item.h \ playlist/notify.c \ diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 8ec4da9470da8fa2f45426699d67f7de5e29fdec..552e6a958c57c4cbb384aa870d1500833db4d02c 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -938,6 +938,8 @@ vlc_playlist_item_Hold vlc_playlist_item_Release vlc_playlist_item_GetMedia vlc_playlist_item_GetId +vlc_playlist_view_Count +vlc_playlist_view_Get vlc_playlist_New vlc_playlist_Delete vlc_playlist_Lock @@ -975,6 +977,7 @@ vlc_playlist_Stop vlc_playlist_Pause vlc_playlist_Resume vlc_playlist_Preparse +vlc_playlist_Export vlc_intf_GetMainPlaylist vlc_media_source_Hold vlc_media_source_Release diff --git a/src/playlist/export.c b/src/playlist/export.c new file mode 100644 index 0000000000000000000000000000000000000000..e9f3ab5e0582772620b8d32f0d1571dc585e8da5 --- /dev/null +++ b/src/playlist/export.c @@ -0,0 +1,104 @@ +/***************************************************************************** + * playlist/export.c + ***************************************************************************** + * Copyright (C) 2019 VLC authors and VideoLAN + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <vlc_playlist_export.h> + +#include <errno.h> +#include <stdio.h> + +#include <vlc_common.h> +#include <vlc_fs.h> +#include <vlc_modules.h> +#include <vlc_url.h> +#include "playlist.h" +#include "libvlc.h" + +struct vlc_playlist_view +{ + vlc_playlist_t *playlist; +}; + +size_t +vlc_playlist_view_Count(struct vlc_playlist_view *view) +{ + return vlc_playlist_Count(view->playlist); +} + +vlc_playlist_item_t * +vlc_playlist_view_Get(struct vlc_playlist_view *view, size_t index) +{ + return vlc_playlist_Get(view->playlist, index); +} + +int +vlc_playlist_Export(struct vlc_playlist *playlist, const char *filename, + const char *type) +{ + vlc_playlist_AssertLocked(playlist); + + struct vlc_playlist_export *export = + vlc_custom_create(vlc_player_GetObject(playlist->player), + sizeof(*export), "playlist export"); + + if (!export) + return VLC_ENOMEM; + + int ret = VLC_EGENERIC; + + struct vlc_playlist_view playlist_view = { .playlist = playlist }; + + export->playlist_view = &playlist_view; + export->base_url = vlc_path2uri(filename, NULL); + export->file = vlc_fopen(filename, "wt"); + if (!export->file) + { + msg_Err(export, "Could not create playlist file %s, %s", + filename, vlc_strerror_c(errno)); + goto close_file; + } + + // this will actually export + module_t *module = module_need(export, "playlist export", type, true); + + if (!module) + { + msg_Err(export, "Could not export playlist"); + goto out; + } + + module_unneed(export, module); + + if (!ferror(export->file)) + ret = VLC_SUCCESS; + else + msg_Err(export, "Could not write playlist file: %s", + vlc_strerror_c(errno)); + +close_file: + fclose(export->file); +out: + free(export->base_url); + vlc_object_delete(export); + return ret; +}