Last week when I wrote about the BBC iPlayer addin for the the Raspberry Piand I got it working on the standard Debian build with VLC Player which was ok for testing but playback performance pretty poor. So I thought what would be a more useful project if the Raspberry Pi could download the BBC shows and then serve them out so I could watch them from devices like iPhone, TVs and PCs using UPNP. Of course you could just stream BBC shows via iPlayer and not bother downloading them but this way works with devices that are not supported by iPlayer and you get to keep the files. So there are two parts to the project, there is the iPlayer downloading software and there is the UPNP server. On the client side all you will need is a UPNP client and we can look at that later.
Part One – UPNP Server
There are a few different ways to achieve this and the one I am going to use is MediaTomb. To get this installed you can either download the SqueezePlug for the Pi and install a UPNP server form there (see this postfor details) or you can install MediaTomb directly from your Debian build. Installing MediaTomb is pretty simple as is a Debain package for it, so just type:
sudo apt-get install mediatomb
After installing MediaTomb you can access it via the browser using the IP address of the Raspberry Pi and the default port which is 49152, so it would be http://yourpiaddress:49152and the user name “mediatomb” with the password “mediatomb”. You can change the port, username and password by editing the XML file
sudo nano /etc/mediatomb/config.xml
We will come back to MediaTomb after we have the iPlayer part working.
Part Two – iPlayer
To get the iPlayer video files you can use a great Linux program called get_iplayer. To get this working you need to get the application and some modules to convert the file to mp4 automatically (details taken from this post). First get the program :
Next extract the gz file and un-compress the tar file:
sudo gzip -d get_iplayer-2.82.tar.gz
sudo tar -xf get_iplayer-2.82.tar
Next there are a couple of permission issues to fix:
sudo chmod 755 get_iplayer
sudo chmod 777 get_iplayer
Now to install the perl, flvstreamer and ffmpeg modules:
sudo apt-get install libwww-perl
sudo apt-get install rtmpdump
sudo apt-get install flvstreamer
sudo apt-get install ffmpeg
Next I created a directory to dump the content into and tell the program to put the files there.
mkdir /iplayer export IPLAYER_OUTDIR=”/iplayer”
Now you can go back to the Mediatomb browser and add the iplayer folder to the database. To do this login via the browser, click on the Filesystem link and from the folder tree select the iplayer folder and click on the + icon. This adds the folder to the upnp server and any content downloaded from iPlayer will show up in this folder.
Now you can download BBC shows via the command line and you need to know the ID of the show to download it. You can find the ID by doing a search from the command line: First run the program
./get_iplayer
Then you search by using ./get_iplayer search term e.g
./get_iplayer “Formula 1”
Which in my case lists two shows, to download the show you need the id number
./get_iplayer –get 302
A .flv file is downloaded which then gets automatically converted to a mp4. You can stream that file from a UPNP client. I tried it on XBMC and my Samsung Galaxy Note and it worked fine, you can also use Windows Media Player or any UPNP/DLNA client. For this project there is a lot more still to do, I want to come up with a UI that is better than the command line UI I have at the moment. I am using SSH to get on to the Raspberry Pi remotely so it’s a headless system but it would be nice to have a GUI for it. Also you could automate the capture of the TV shows, so you could create a script that checks for new shows and automatically downloads them. Part three will look at the UI and automation.
3 thoughts on “Project: BBC iPlayer server for the Raspberry Pi”
A couple of points:
1. If you’re going to “sudo” wget, gzip and the like, you might as well just “sudo” bash and be done with it!
2. Did you really mean this line to look like this?: “sudo chmod 755 get_iplayer sudo chmod 777 get_iplayer” – you’re changing the mode on the same target twice as far as I can see, and the second time to rwxrwxrwx?
3. If you pass the –get parameter to get_iplayer when searching it will go on and download anything that matches your search (e.g. get_iplayer –get “Formula 1”), so if you’re confident in what your search will match then you don’t need to muck about with id numbers. It’s also smart enough to not re-download anything it’s downloaded before (even if you’ve since deleted it – –force overrides that behaviour)
4. get_iplayer has a whole bunch of “PVR” options that let you schedule recordings and download new instances as they become available, so your script for automating the capture could turn out to be very simple really.
All you need now is a light web server with a bit of clever web scripting to manage the scheduling of recordings and you’re away 🙂
I have completed a similar project, which automatically downloads content from iPlayer using get_iplayer’s PVR function and creates a podcast RSS feed which I then subscribe to from my phone, ipod, pc.
You may find it useful to use the Web UI which comes with get_iplayer, as an alternative to find and downloading programs via a command line
By using the PVR functions of get_iplayer you can also subscribe to a complete series which if then run as a scheduled job will automatically download content as and when it appears in iPlayer.
{"id":null,"mode":"button","open_style":"in_place","currency_code":"GBP","currency_symbol":"\u00a3","currency_type":"decimal","blank_flag_url":"https:\/\/thedigitallifestyle.com\/w\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/blank.gif","flag_sprite_url":"https:\/\/thedigitallifestyle.com\/w\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/flags.png","default_amount":500,"top_media_type":"none","featured_image_url":false,"featured_embed":"","header_media":null,"file_download_attachment_data":null,"recurring_options_enabled":true,"recurring_options":{"never":{"selected":true,"after_output":"One time only"},"weekly":{"selected":false,"after_output":"Every week"},"monthly":{"selected":false,"after_output":"Every month"},"yearly":{"selected":false,"after_output":"Every year"}},"strings":{"current_user_email":"","current_user_name":"","link_text":"Leave a tip","complete_payment_button_error_text":"Check info and try again","payment_verb":"Pay","payment_request_label":"TheDigitalLifestyle.com","form_has_an_error":"Please check and fix the errors above","general_server_error":"Something isn't working right at the moment. Please try again.","form_title":"TheDigitalLifestyle.com","form_subtitle":null,"currency_search_text":"Country or Currency here","other_payment_option":"Other payment option","manage_payments_button_text":"Manage your payments","thank_you_message":"Thank you for being a supporter!","payment_confirmation_title":"TheDigitalLifestyle.com","receipt_title":"Your Receipt","print_receipt":"Print Receipt","email_receipt":"Email Receipt","email_receipt_sending":"Sending receipt...","email_receipt_success":"Email receipt successfully sent","email_receipt_failed":"Email receipt failed to send. Please try again.","receipt_payee":"Paid to","receipt_statement_descriptor":"This will show up on your statement as","receipt_date":"Date","receipt_transaction_id":"Transaction ID","receipt_transaction_amount":"Amount","refund_payer":"Refund from","login":"Log in to manage your payments","manage_payments":"Manage Payments","transactions_title":"Your Transactions","transaction_title":"Transaction Receipt","transaction_period":"Plan Period","arrangements_title":"Your Plans","arrangement_title":"Manage Plan","arrangement_details":"Plan Details","arrangement_id_title":"Plan ID","arrangement_payment_method_title":"Payment Method","arrangement_amount_title":"Plan Amount","arrangement_renewal_title":"Next renewal date","arrangement_action_cancel":"Cancel Plan","arrangement_action_cant_cancel":"Cancelling is currently not available.","arrangement_action_cancel_double":"Are you sure you'd like to cancel?","arrangement_cancelling":"Cancelling Plan...","arrangement_cancelled":"Plan Cancelled","arrangement_failed_to_cancel":"Failed to cancel plan","back_to_plans":"\u2190 Back to Plans","update_payment_method_verb":"Update","sca_auth_description":"Your have a pending renewal payment which requires authorization.","sca_auth_verb":"Authorize renewal payment","sca_authing_verb":"Authorizing payment","sca_authed_verb":"Payment successfully authorized!","sca_auth_failed":"Unable to authorize! Please try again.","login_button_text":"Log in","login_form_has_an_error":"Please check and fix the errors above","uppercase_search":"Search","lowercase_search":"search","uppercase_page":"Page","lowercase_page":"page","uppercase_items":"Items","lowercase_items":"items","uppercase_per":"Per","lowercase_per":"per","uppercase_of":"Of","lowercase_of":"of","back":"Back to plans","zip_code_placeholder":"Zip\/Postal Code","download_file_button_text":"Download File","input_field_instructions":{"tip_amount":{"placeholder_text":"How much would you like to tip?","initial":{"instruction_type":"normal","instruction_message":"How much would you like to tip? Choose any currency."},"empty":{"instruction_type":"error","instruction_message":"How much would you like to tip? Choose any currency."},"invalid_curency":{"instruction_type":"error","instruction_message":"Please choose a valid currency."}},"recurring":{"placeholder_text":"Recurring","initial":{"instruction_type":"normal","instruction_message":"How often would you like to give this?"},"success":{"instruction_type":"success","instruction_message":"How often would you like to give this?"},"empty":{"instruction_type":"error","instruction_message":"How often would you like to give this?"}},"name":{"placeholder_text":"Name on Credit Card","initial":{"instruction_type":"normal","instruction_message":"Enter the name on your card."},"success":{"instruction_type":"success","instruction_message":"Enter the name on your card."},"empty":{"instruction_type":"error","instruction_message":"Please enter the name on your card."}},"privacy_policy":{"terms_title":"Terms and conditions","terms_body":null,"terms_show_text":"View Terms","terms_hide_text":"Hide Terms","initial":{"instruction_type":"normal","instruction_message":"I agree to the terms."},"unchecked":{"instruction_type":"error","instruction_message":"Please agree to the terms."},"checked":{"instruction_type":"success","instruction_message":"I agree to the terms."}},"email":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email address"},"success":{"instruction_type":"success","instruction_message":"Enter your email address"},"blank":{"instruction_type":"error","instruction_message":"Enter your email address"},"not_an_email_address":{"instruction_type":"error","instruction_message":"Make sure you have entered a valid email address"}},"note_with_tip":{"placeholder_text":"Your note here...","initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"empty":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"not_empty_initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"saving":{"instruction_type":"normal","instruction_message":"Saving note..."},"success":{"instruction_type":"success","instruction_message":"Note successfully saved!"},"error":{"instruction_type":"error","instruction_message":"Unable to save note note at this time. Please try again."}},"email_for_login_code":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email to log in."},"success":{"instruction_type":"success","instruction_message":"Enter your email to log in."},"blank":{"instruction_type":"error","instruction_message":"Enter your email to log in."},"empty":{"instruction_type":"error","instruction_message":"Enter your email to log in."}},"login_code":{"initial":{"instruction_type":"normal","instruction_message":"Check your email and enter the login code."},"success":{"instruction_type":"success","instruction_message":"Check your email and enter the login code."},"blank":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."},"empty":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."}},"stripe_all_in_one":{"initial":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"empty":{"instruction_type":"error","instruction_message":"Enter your credit card details here."},"success":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"invalid_number":{"instruction_type":"error","instruction_message":"The card number is not a valid credit card number."},"invalid_expiry_month":{"instruction_type":"error","instruction_message":"The card's expiration month is invalid."},"invalid_expiry_year":{"instruction_type":"error","instruction_message":"The card's expiration year is invalid."},"invalid_cvc":{"instruction_type":"error","instruction_message":"The card's security code is invalid."},"incorrect_number":{"instruction_type":"error","instruction_message":"The card number is incorrect."},"incomplete_number":{"instruction_type":"error","instruction_message":"The card number is incomplete."},"incomplete_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incomplete."},"incomplete_expiry":{"instruction_type":"error","instruction_message":"The card's expiration date is incomplete."},"incomplete_zip":{"instruction_type":"error","instruction_message":"The card's zip code is incomplete."},"expired_card":{"instruction_type":"error","instruction_message":"The card has expired."},"incorrect_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incorrect."},"incorrect_zip":{"instruction_type":"error","instruction_message":"The card's zip code failed validation."},"invalid_expiry_year_past":{"instruction_type":"error","instruction_message":"The card's expiration year is in the past"},"card_declined":{"instruction_type":"error","instruction_message":"The card was declined."},"missing":{"instruction_type":"error","instruction_message":"There is no card on a customer that is being charged."},"processing_error":{"instruction_type":"error","instruction_message":"An error occurred while processing the card."},"invalid_request_error":{"instruction_type":"error","instruction_message":"Unable to process this payment, please try again or use alternative method."},"invalid_sofort_country":{"instruction_type":"error","instruction_message":"The billing country is not accepted by SOFORT. Please try another country."}}}},"fetched_oembed_html":false}
A couple of points:
1. If you’re going to “sudo” wget, gzip and the like, you might as well just “sudo” bash and be done with it!
2. Did you really mean this line to look like this?: “sudo chmod 755 get_iplayer sudo chmod 777 get_iplayer” – you’re changing the mode on the same target twice as far as I can see, and the second time to rwxrwxrwx?
3. If you pass the –get parameter to get_iplayer when searching it will go on and download anything that matches your search (e.g. get_iplayer –get “Formula 1”), so if you’re confident in what your search will match then you don’t need to muck about with id numbers. It’s also smart enough to not re-download anything it’s downloaded before (even if you’ve since deleted it – –force overrides that behaviour)
4. get_iplayer has a whole bunch of “PVR” options that let you schedule recordings and download new instances as they become available, so your script for automating the capture could turn out to be very simple really.
All you need now is a light web server with a bit of clever web scripting to manage the scheduling of recordings and you’re away 🙂
Cheers, Steve
Good points, I will update the post. If it was .net I could write the UI and scripting in about 10 mins but its not 🙂
I have completed a similar project, which automatically downloads content from iPlayer using get_iplayer’s PVR function and creates a podcast RSS feed which I then subscribe to from my phone, ipod, pc.
You may find it useful to use the Web UI which comes with get_iplayer, as an alternative to find and downloading programs via a command line
By using the PVR functions of get_iplayer you can also subscribe to a complete series which if then run as a scheduled job will automatically download content as and when it appears in iPlayer.
See Raspberry Pi – BBC iPlayer Personal Podcast for how the Pi makes this work.