onsdag den 11. marts 2015

Status for Universal Power Adapter for Mobile Devices

I was curious abotu whether IEEE's Universal Power Adapter for Mobile Devices standard had been abandoned. Jonathan Goldberg of IEEE was kind enough to answer my email:
Thue,

Good afternoon. In fact, P1823 recently completed a recirculation ballot and has been submitted to the IEEE Standards Review Committee (RevCom) for December 2014 review and possible approval by the IEEE Standards Association Standards Board. 

Please let me know if you have any further questions on this project.

Regards,

Jonathan Goldberg
Client Services Manager
IEEE Standards Association

p: +1 732 562 6088
c: +1 732 570 0116
f:  +1 732 562 1571
e: goldberg.j@ieee.org

IEEE - Fostering technological innovation and excellence for the benefit of humanity.

On Wed, Sep 24, 2014 at 12:04 PM, IEEE Standards webmail  wrote:
(Message sent via IEEE Standards webmail)
-----------------------------------------

referer = http://standards.ieee.org/develop/project/1823.html
first_name = Thue
last_name = Kristensen
email = thuejk@gmail.com
email_confirm = thuejk@gmail.com
message = While updating https://en.wikipedia.org/wiki/Universal_Power_Adapter_for_Mobile_Devices , I noted that there have been no meeting minutes published since 2012, so I assume there have been no meetings.

Does this mean that the P1823 standard is dead, perhaps superseeded by IEC 62700, or is it only sleeping?
preferred_contact_method = Email
daytime_phone1 = (not supplied)
daytime_phone2 = (not supplied)
daytime_phone3 = (not supplied)
country_code = (not supplied)
extension = (not supplied)
referral_type = select one
contact_submit = Submit


-----------------------------------------
(End of IEEE Standards webmail message)

mandag den 3. juni 2013

Dashed line error in Apple PDF viewer

I had the Apple PDF viewer choke on a PDF document which worked wine in other PDF viewers. I tracked it down to a funny dashed line. As can be seen on page 155 of the PDF specification for the third edition, dashed lines are specified as fx "[1 2] 0", which means 1 unit on, 2 units off. To stop dashing, you should write a dash specification of "[] 0".

I had a pdf which tried to stop dashing by writing "[ 1 0 ] 0" ("[ 1 0 ] 0 d" actually, I haven't looked into what the "d" means). This worked fine in most PDF viewers, but in Apple's viewer the document stopped rendering at that point. I assume that it is the 0-gap (the first "0") which confuses it. Fixing the PDF generator to use the "[] 0 d" from the specification made it work in Apple's PDF viewer.

So now you know, if you come across the same problem :). I would report it to Apple, but they don't seem to let you report bugs if you do not have an Apple ID.

onsdag den 28. december 2011

The Sharing Knife

I liked the fantasy novels The Sharing Knife, so I asked Lois McMaster Bujold (the author) by email if more books in that series we planned. Her answer:

Hi Thue --

No, only the 4 so far. Nothing else is planned at this time.

There is, of course, a new Vorkosigan SF book coming out in November, _CryoBurn_.

bests, Lois.


Too bad :(

søndag den 25. september 2011

Kom uden om DR's flash-afspiller

Jeg ser nogen gange Bonderøven på DR1. Men selv om programmerne er tilgængelige via flash-afspilleren, så er DR er langsomme til at lægge programmerne ud til download. Flash-afspilleren er ret irriterende, da man for eksempel ikke kan putte den i fuldscreen, og så samtidigt klikke rundt på sin sekundære skærm.

Så siden flash-afspilleren må hente videoen et sted fra, så må jeg da også kunne hente den derfra, og så afspille den fra den downloadede fil.

Første trin er at bruge Chromium's developer tools til at "inspecte" flashplayeren på http://www.dr.dk/dr1/bonderoeven . Den har kildekoden

<object id="nettvPlayer" height="349px" width="620px" type="application/x-shockwave-flash" data="/nu/assets/swf/NetTVPlayer_10.swf">
<param name="quality" value="high">
<param name="allowScriptAccess" value="always">
<param name="wMode" value="transparent">
<param name="swLiveConnect" value="true">
<param name="bgcolor" value="#000000">
<param name="AllowScriptAccess" value="sameDomain">
<param name="AllowFullScreen" value="true">
<param name="flashVars" value="data=%7B%22swf%22%3A%22%2Fnu%2Fassets%2Fswf%2FNetTVPlayer_10.swf%22%2C%22height%22%3A%22349px%22%2C%22width%22%3A%22620px%22%2C%22version%22%3A%229.1.0%22%2C%22smoothing%22%3Afalse%2C%22loopPlaylist%22%3Afalse%2C%22autoplay%22%3Atrue%2C%22wmode%22%3A%22transparent%22%2C%22bgcolor%22%3A%22%23000000%22%2C%22geoLocationServiceUrl%22%3A%22http%3A%2F%2Fwww.dr.dk%2Ftjenester%2Fgeolocation%2FGeoLocation.asmx%2FGet%22%2C%22popup%22%3Afalse%2C%22color%22%3A%22%22%2C%22content%22%3A%22od%2Fbonderoeven%2F%22%2C%22live%22%3Afalse%2C%22showChannels%22%3Atrue%2C%22urls%22%3A%7B%22popupUrl%22%3A%22%2Fnu%2Fpopup%2F%22%2C%22seriesImageUrl%22%3A%22%2Fnu%2Fapi%2Fprogramseries%2F%7Bslug%7D%2Fimages%2F%7Bwidth%7Dx%7Bheight%7D.jpg%22%2C%22episodeImageUrl%22%3A%22%2Fnu%2Fapi%2Fvideos%2F%7Bid%7D%2Fimages%2F%7Bwidth%7Dx%7Bheight%7D.jpg%22%2C%22episodesUrl%22%3A%22%2Fnu%2Fapi%2Fprogramseries%2F%7Bslug%7D%2Fvideos%22%2C%22videoUrl%22%3A%22%2Fnu%2Fapi%2Fvideos%2F%7BvideoId%7D%22%2C%22registerView%22%3A%22%2Fnu%2Fapi%2FVideoView%2F%7BvideoId%7D%2F%7BuserId%7D%2F%7BrtmpVideoHost%7D%22%2C%22registerFedoraView%22%3A%22http%3A%2F%2F77.66.32.234%2Fcammpdrnu%2Fmobilwebapp%3Fxslt%3DcopyXml%26service%3DshowClipInfo%26externalId%3D%7BvideoId%7D%26loginName%3D%7BuserId%7D%22%2C%22registerChapterView%22%3A%22%22%2C%22seriesUrl%22%3A%22%2Fnu%2Fapi%2Fprogramseries%22%2C%22flashStatisticUrl%22%3A%22%22%2C%22reportErrorUrl%22%3A%22%2Fnu%2Ffeedback%2F%22%2C%22geoFilterUrl%22%3A%22%2Fnu%2Fgeofilter%2F%22%2C%22liveDeeplink%22%3A%22http%3A%2F%2Fwww.dr.dk%2Fnu%2Flive%2Fse%22%2C%22onDemandDeeplink%22%3A%22http%3A%2F%2Fwww.dr.dk%2Fnu%2Fse%22%2C%22chapterImageUrl%22%3A%22%2Fnu%2Fapi%2Fchapters%2F%7BchapterId%7D%2Fimages%2F%7Bwidth%7Dx%7Bheight%7D.jpg%22%7D%2C%22modules%22%3A%5B%7B%22className%22%3A%22Gemius%22%2C%22parameters%22%3A%7B%22encoding%22%3A%22utf-8%22%2C%22identifier%22%3A%22p9AwR.N.S86s_NjaJKdww7b.fdp8ky90ZnrKpgLHOUn.s7%22%2C%22hitCollector%22%3A%22http%3A%2F%2Fsdk.hit.gemius.pl%22%2C%22playerId%22%3A%22UPlayer%22%7D%7D%2C%7B%22className%22%3A%22JavaScript%22%2C%22parameters%22%3A%7B%7D%7D%5D%2C%22liveStreams%22%3A%5B%7B%22channelName%22%3A%22DR1%22%2C%22gemius_customPackage%22%3A%5B%7B%22name%22%3A%22CHANNEL%22%2C%22value%22%3A%22LIVE%22%7D%2C%7B%22name%22%3A%22PROGRAMME%22%2C%22value%22%3A%22DR1%22%7D%2C%7B%22name%22%3A%22AUTOSTART%22%2C%22value%22%3A%22YES%22%7D%5D%2C%22gemius_materialId%22%3A%22019_LIVE-DR1%26DR1%22%2C%22gemius_live%22%3Atrue%2C%22mediaFiles%22%3A%5B%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr01astream3%22%2C%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr01bstream3%22%2C%22rtmp%3A%2F%2Flivetv.gss.dr.dk%2Flive%2Ffv2011stream3%22%2C%22rtmp%3A%2F%2Ffl0.c41003.cdn.qbrick.com%2F41003%2Ffv2011stream3%22%5D%2C%22kbps%22%3A1000%7D%2C%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr01astream2%22%2C%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr01bstream2%22%2C%22rtmp%3A%2F%2Flivetv.gss.dr.dk%2Flive%2Ffv2011stream2%22%2C%22rtmp%3A%2F%2Ffl0.c41003.cdn.qbrick.com%2F41003%2Ffv2011stream2%22%5D%2C%22kbps%22%3A500%7D%2C%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr01astream1%22%2C%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr01bstream1%22%2C%22rtmp%3A%2F%2Flivetv.gss.dr.dk%2Flive%2Ffv2011stream1%22%2C%22rtmp%3A%2F%2Ffl0.c41003.cdn.qbrick.com%2F41003%2Ffv2011stream1%22%5D%2C%22kbps%22%3A250%7D%5D%7D%2C%7B%22channelName%22%3A%22DR2%22%2C%22gemius_customPackage%22%3A%5B%7B%22name%22%3A%22CHANNEL%22%2C%22value%22%3A%22LIVE%22%7D%2C%7B%22name%22%3A%22PROGRAMME%22%2C%22value%22%3A%22DR2%22%7D%2C%7B%22name%22%3A%22AUTOSTART%22%2C%22value%22%3A%22YES%22%7D%5D%2C%22gemius_materialId%22%3A%22019_LIVE-DR2%26DR2%22%2C%22gemius_live%22%3Atrue%2C%22mediaFiles%22%3A%5B%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr02astream3%22%2C%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr02bstream3%22%5D%2C%22kbps%22%3A1000%7D%2C%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr02astream2%22%2C%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr02bstream2%22%5D%2C%22kbps%22%3A500%7D%2C%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr02astream1%22%2C%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr02bstream1%22%5D%2C%22kbps%22%3A250%7D%5D%7D%2C%7B%22channelName%22%3A%22DR%20K%22%2C%22gemius_customPackage%22%3A%5B%7B%22name%22%3A%22CHANNEL%22%2C%22value%22%3A%22LIVE%22%7D%2C%7B%22name%22%3A%22PROGRAMME%22%2C%22value%22%3A%22DR%20K%22%7D%2C%7B%22name%22%3A%22AUTOSTART%22%2C%22value%22%3A%22YES%22%7D%5D%2C%22gemius_materialId%22%3A%22019_LIVE-DR%20K%26DR%20K%22%2C%22gemius_live%22%3Atrue%2C%22mediaFiles%22%3A%5B%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr04astream3%22%2C%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr04bstream3%22%5D%2C%22kbps%22%3A1000%7D%2C%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr04astream2%22%2C%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr04bstream2%22%5D%2C%22kbps%22%3A500%7D%2C%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr04astream1%22%2C%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr04bstream1%22%5D%2C%22kbps%22%3A250%7D%5D%7D%2C%7B%22channelName%22%3A%22DR%20Ramasjang%22%2C%22gemius_customPackage%22%3A%5B%7B%22name%22%3A%22CHANNEL%22%2C%22value%22%3A%22LIVE%22%7D%2C%7B%22name%22%3A%22PROGRAMME%22%2C%22value%22%3A%22DR%20Ramasjang%22%7D%2C%7B%22name%22%3A%22AUTOSTART%22%2C%22value%22%3A%22YES%22%7D%5D%2C%22gemius_materialId%22%3A%22019_LIVE-DR%20Ramasjang%26DR%20Ramasjang%22%2C%22gemius_live%22%3Atrue%2C%22mediaFiles%22%3A%5B%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr05astream3%22%2C%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr05bstream3%22%5D%2C%22kbps%22%3A1000%7D%2C%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr05astream2%22%2C%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr05bstream2%22%5D%2C%22kbps%22%3A500%7D%2C%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr05astream1%22%2C%22rtmp%3A%2F%2Frtmplive.dr.dk%2Flive%2Flivedr05bstream1%22%5D%2C%22kbps%22%3A250%7D%5D%7D%2C%7B%22channelName%22%3A%22DR%20Update%22%2C%22gemius_customPackage%22%3A%5B%7B%22name%22%3A%22CHANNEL%22%2C%22value%22%3A%22LIVE%22%7D%2C%7B%22name%22%3A%22PROGRAMME%22%2C%22value%22%3A%22DR%20Update%22%7D%2C%7B%22name%22%3A%22AUTOSTART%22%2C%22value%22%3A%22YES%22%7D%5D%2C%22gemius_materialId%22%3A%22019_LIVE-DR%20Update%26DR%20Update%22%2C%22gemius_live%22%3Atrue%2C%22mediaFiles%22%3A%5B%7B%22mediaFile%22%3A%22rtmp%3A%2F%2Flivetv.gss.dr.dk%2Flive%2Flivedr03astream3%22%2C%22kbps%22%3A1000%7D%2C%7B%22mediaFile%22%3A%22rtmp%3A%2F%2Flivetv.gss.dr.dk%2Flive%2Flivedr03astream2%22%2C%22kbps%22%3A500%7D%2C%7B%22mediaFile%22%3A%22rtmp%3A%2F%2Flivetv.gss.dr.dk%2Flive%2Flivedr03astream1%22%2C%22kbps%22%3A250%7D%5D%7D%2C%7B%22channelName%22%3A%22DR%20HD%22%2C%22gemius_customPackage%22%3A%5B%7B%22name%22%3A%22CHANNEL%22%2C%22value%22%3A%22LIVE%22%7D%2C%7B%22name%22%3A%22PROGRAMME%22%2C%22value%22%3A%22DR%20HD%22%7D%2C%7B%22name%22%3A%22AUTOSTART%22%2C%22value%22%3A%22YES%22%7D%5D%2C%22gemius_materialId%22%3A%22019_LIVE-DR%20HD%26DR%20HD%22%2C%22gemius_live%22%3Atrue%2C%22mediaFiles%22%3A%5B%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Flivetv.gss.dr.dk%2Flive%2Flivedr06astream3%22%2C%22rtmp%3A%2F%2Flivetv.gss.dr.dk%2Flive%2Flivedr06bstream3%22%5D%2C%22kbps%22%3A1700%7D%2C%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Flivetv.gss.dr.dk%2Flive%2Flivedr06astream2%22%2C%22rtmp%3A%2F%2Flivetv.gss.dr.dk%2Flive%2Flivedr06bstream2%22%5D%2C%22kbps%22%3A1000%7D%2C%7B%22mediaFile%22%3A%5B%22rtmp%3A%2F%2Flivetv.gss.dr.dk%2Flive%2Flivedr06astream1%22%2C%22rtmp%3A%2F%2Flivetv.gss.dr.dk%2Flive%2Flivedr06bstream1%22%5D%2C%22kbps%22%3A500%7D%5D%7D%5D%7D&onLoad=Swiff.CallBacks.Swiff_1316964073832.onLoad&onData=Swiff.CallBacks.Swiff_1316964073832.onData&onSkip=Swiff.CallBacks.Swiff_1316964073832.onSkip&onStateChange=Swiff.CallBacks.Swiff_1316964073832.onStateChange&onShare=Swiff.CallBacks.Swiff_1316964073832.onShare&onPopup=Swiff.CallBacks.Swiff_1316964073832.onPopup&onRequestNowNext=Swiff.CallBacks.Swiff_1316964073832.onRequestNowNext&onContentPathChange=Swiff.CallBacks.Swiff_1316964073832.onContentPathChange"></object>


Her set det ud til at indholdet af "flashVars" er det interessante. Et gæt er, at det er urlencoded, så efter det er kørt igennem http://meyerweb.com/eric/tools/dencoder/ bliver det til

data={"swf":"/nu/assets/swf/NetTVPlayer_10.swf","height":"349px","width":"620px","version":"9.1.0","smoothing":false,"loopPlaylist":false,"autoplay":true,"wmode":"transparent","bgcolor":"#000000","geoLocationServiceUrl":"http://www.dr.dk/tjenester/geolocation/GeoLocation.asmx/Get","popup":false,"color":"","content":"od/bonderoeven/","live":false,"showChannels":true,"urls":{"popupUrl":"/nu/popup/","seriesImageUrl":"/nu/api/programseries/{slug}/images/{width}x{height}.jpg","episodeImageUrl":"/nu/api/videos/{id}/images/{width}x{height}.jpg","episodesUrl":"/nu/api/programseries/{slug}/videos","videoUrl":"/nu/api/videos/{videoId}","registerView":"/nu/api/VideoView/{videoId}/{userId}/{rtmpVideoHost}","registerFedoraView":"http://77.66.32.234/cammpdrnu/mobilwebapp?xslt=copyXml&service=showClipInfo&externalId={videoId}&loginName={userId}","registerChapterView":"","seriesUrl":"/nu/api/programseries","flashStatisticUrl":"","reportErrorUrl":"/nu/feedback/","geoFilterUrl":"/nu/geofilter/","liveDeeplink":"http://www.dr.dk/nu/live/se","onDemandDeeplink":"http://www.dr.dk/nu/se","chapterImageUrl":"/nu/api/chapters/{chapterId}/images/{width}x{height}.jpg"},"modules":[{"className":"Gemius","parameters":{"encoding":"utf-8","identifier":"p9AwR.N.S86s_NjaJKdww7b.fdp8ky90ZnrKpgLHOUn.s7","hitCollector":"http://sdk.hit.gemius.pl","playerId":"UPlayer"}},{"className":"JavaScript","parameters":{}}],"liveStreams":[{"channelName":"DR1","gemius_customPackage":[{"name":"CHANNEL","value":"LIVE"},{"name":"PROGRAMME","value":"DR1"},{"name":"AUTOSTART","value":"YES"}],"gemius_materialId":"019_LIVE-DR1&DR1","gemius_live":true,"mediaFiles":[{"mediaFile":["rtmp://rtmplive.dr.dk/live/livedr01astream3","rtmp://rtmplive.dr.dk/live/livedr01bstream3","rtmp://livetv.gss.dr.dk/live/fv2011stream3","rtmp://fl0.c41003.cdn.qbrick.com/41003/fv2011stream3"],"kbps":1000},{"mediaFile":["rtmp://rtmplive.dr.dk/live/livedr01astream2","rtmp://rtmplive.dr.dk/live/livedr01bstream2","rtmp://livetv.gss.dr.dk/live/fv2011stream2","rtmp://fl0.c41003.cdn.qbrick.com/41003/fv2011stream2"],"kbps":500},{"mediaFile":["rtmp://rtmplive.dr.dk/live/livedr01astream1","rtmp://rtmplive.dr.dk/live/livedr01bstream1","rtmp://livetv.gss.dr.dk/live/fv2011stream1","rtmp://fl0.c41003.cdn.qbrick.com/41003/fv2011stream1"],"kbps":250}]},{"channelName":"DR2","gemius_customPackage":[{"name":"CHANNEL","value":"LIVE"},{"name":"PROGRAMME","value":"DR2"},{"name":"AUTOSTART","value":"YES"}],"gemius_materialId":"019_LIVE-DR2&DR2","gemius_live":true,"mediaFiles":[{"mediaFile":["rtmp://rtmplive.dr.dk/live/livedr02astream3","rtmp://rtmplive.dr.dk/live/livedr02bstream3"],"kbps":1000},{"mediaFile":["rtmp://rtmplive.dr.dk/live/livedr02astream2","rtmp://rtmplive.dr.dk/live/livedr02bstream2"],"kbps":500},{"mediaFile":["rtmp://rtmplive.dr.dk/live/livedr02astream1","rtmp://rtmplive.dr.dk/live/livedr02bstream1"],"kbps":250}]},{"channelName":"DR K","gemius_customPackage":[{"name":"CHANNEL","value":"LIVE"},{"name":"PROGRAMME","value":"DR K"},{"name":"AUTOSTART","value":"YES"}],"gemius_materialId":"019_LIVE-DR K&DR K","gemius_live":true,"mediaFiles":[{"mediaFile":["rtmp://rtmplive.dr.dk/live/livedr04astream3","rtmp://rtmplive.dr.dk/live/livedr04bstream3"],"kbps":1000},{"mediaFile":["rtmp://rtmplive.dr.dk/live/livedr04astream2","rtmp://rtmplive.dr.dk/live/livedr04bstream2"],"kbps":500},{"mediaFile":["rtmp://rtmplive.dr.dk/live/livedr04astream1","rtmp://rtmplive.dr.dk/live/livedr04bstream1"],"kbps":250}]},{"channelName":"DR Ramasjang","gemius_customPackage":[{"name":"CHANNEL","value":"LIVE"},{"name":"PROGRAMME","value":"DR Ramasjang"},{"name":"AUTOSTART","value":"YES"}],"gemius_materialId":"019_LIVE-DR Ramasjang&DR Ramasjang","gemius_live":true,"mediaFiles":[{"mediaFile":["rtmp://rtmplive.dr.dk/live/livedr05astream3","rtmp://rtmplive.dr.dk/live/livedr05bstream3"],"kbps":1000},{"mediaFile":["rtmp://rtmplive.dr.dk/live/livedr05astream2","rtmp://rtmplive.dr.dk/live/livedr05bstream2"],"kbps":500},{"mediaFile":["rtmp://rtmplive.dr.dk/live/livedr05astream1","rtmp://rtmplive.dr.dk/live/livedr05bstream1"],"kbps":250}]},{"channelName":"DR Update","gemius_customPackage":[{"name":"CHANNEL","value":"LIVE"},{"name":"PROGRAMME","value":"DR Update"},{"name":"AUTOSTART","value":"YES"}],"gemius_materialId":"019_LIVE-DR Update&DR Update","gemius_live":true,"mediaFiles":[{"mediaFile":"rtmp://livetv.gss.dr.dk/live/livedr03astream3","kbps":1000},{"mediaFile":"rtmp://livetv.gss.dr.dk/live/livedr03astream2","kbps":500},{"mediaFile":"rtmp://livetv.gss.dr.dk/live/livedr03astream1","kbps":250}]},{"channelName":"DR HD","gemius_customPackage":[{"name":"CHANNEL","value":"LIVE"},{"name":"PROGRAMME","value":"DR HD"},{"name":"AUTOSTART","value":"YES"}],"gemius_materialId":"019_LIVE-DR HD&DR HD","gemius_live":true,"mediaFiles":[{"mediaFile":["rtmp://livetv.gss.dr.dk/live/livedr06astream3","rtmp://livetv.gss.dr.dk/live/livedr06bstream3"],"kbps":1700},{"mediaFile":["rtmp://livetv.gss.dr.dk/live/livedr06astream2","rtmp://livetv.gss.dr.dk/live/livedr06bstream2"],"kbps":1000},{"mediaFile":["rtmp://livetv.gss.dr.dk/live/livedr06astream1","rtmp://livetv.gss.dr.dk/live/livedr06bstream1"],"kbps":500}]}]}&onLoad=Swiff.CallBacks.Swiff_1316964073832.onLoad&onData=Swiff.CallBacks.Swiff_1316964073832.onData&onSkip=Swiff.CallBacks.Swiff_1316964073832.onSkip&onStateChange=Swiff.CallBacks.Swiff_1316964073832.onStateChange&onShare=Swiff.CallBacks.Swiff_1316964073832.onShare&onPopup=Swiff.CallBacks.Swiff_1316964073832.onPopup&onRequestNowNext=Swiff.CallBacks.Swiff_1316964073832.onRequestNowNext&onContentPathChange=Swiff.CallBacks.Swiff_1316964073832.onContentPathChange


Det meste er det er referencer til DR's kanaler (DR1, DR2, etc), som er irrelevante. Efetr at have formatteret og smidt de åbenlyst irrelevante ting ud er der følgende tilbage:

data = {
"content":"od/bonderoeven/",
"urls":{
"seriesImageUrl":"/nu/api/programseries/{slug}/images/{width}x{height}.jpg",
"episodeImageUrl":"/nu/api/videos/{id}/images/{width}x{height}.jpg",
"episodesUrl":"/nu/api/programseries/{slug}/videos",
"videoUrl":"/nu/api/videos/{videoId}",
"seriesUrl":"/nu/api/programseries",
},
"modules":
[
{
"className":"Gemius",
"parameters":{
"encoding":"utf-8",
"identifier":"p9AwR.N.S86s_NjaJKdww7b.fdp8ky90ZnrKpgLHOUn.s7",
"hitCollector":"http://sdk.hit.gemius.pl",
"playerId":"UPlayer"
}
}
]
}


I sektionen "urls" gætter jeg mig frem til at {slug} er et ID for serien (Bonderøven), og {videoId} er et ID for det enkelte afsnit.

Det viser sig at http://www.dr.dk/nu/api/programseries giver en liste over alle DR's programserier. Bonderøvens indgang i den liste er
{
"slug": "bonderoeven",
"title": "Bonderøven",
"description": "Frank er lidt spændt, for føllet Manfred er til hingstekåring, hvor han skal bedømmes af tyske dommere, sammen med andre Schleswiger-føl. Og så er det dagen, hvor Frank skal høste med selvbinder, men først laver han et nyt selvbindersejl af en rulle lærred han købte, da han var 18 år. Mirabellerne er modne, så hele familien drager ud med spand for at plukke.",
"shortName": null,
"newestVideoId": 18431,
"newestVideoPublishTime": "\/Date(1316543400000+0200)\/",
"videoCount": 32,
"labels": [
"livsstil"
]
},

Så vi gætter på at 18431 er et eksempel på et videoId. Og http://www.dr.dk/nu/api/videos/18431/images/1000x1000.jpg giver da også et pænt billede for det afsnit. Ved at bruge http://www.dr.dk/nu/api/videos/18431 får vi information om afsnittet:
{
"id": 18431,
"description": "Frank er lidt spændt, for føllet Manfred er til hingstekåring, hvor han skal bedømmes af tyske dommere, sammen med andre Schleswiger-føl. Og så er det dagen, hvor Frank skal høste med selvbinder, men først laver han et nyt selvbindersejl af en rulle lærred han købte, da han var 18 år. Mirabellerne er modne, så hele familien drager ud med spand for at plukke.",
"programSerieSlug": "bonderoeven",
"title": "Bonderøven (5:10)",
"duration": "00:27:14",
"broadcastTime": "\/Date(1317148200000+0200)\/",
"expireTime": "\/Date(32503676400000+0100)\/",
"publishTime": "\/Date(-62135596800000+0100)\/",
"expired": false,
"broadcastChannel": "DR1",
"videoManifestUrl": "http://www.dr.dk/Forms/Published/PlaylistGen.aspx?qid=2350582&OnlyWritePath=True",
"videoResourceUrl": "http://www.dr.dk/handlers/GetResource.ashx?id=983628",
"premiere": true,
"rtmpVideoHost": null,
"formattedExpireTime": "1. jan. 3000",
"formattedBroadcastTime": "27. sep. 2011",
"formattedBroadcastTimeForTVSchedule": "tir. d. 27. sep",
"formattedBroadcastHourForTVSchedule": "Kl. 20:30",
"chapters": []
}

Her er videoResourceUrl nok hvor selve videoen er. http://www.dr.dk/handlers/GetResource.ashx?id=983628 giver (efter lidt formattering)
{
"resourceId":983628,
"name":"Bonderøven (5:10) 7. sæson, efterår 2011 ",
"mediaType":"Video",
"restrictedToDenmark":false,
"downloadable":false,
"geofilterId":0,
"publish":"2011-09-19T14:46:32",
"expire":"3000-01-01T00:00:00",
"links":
[
{
"qualityId":2350582,
"uri":"rtmp://vod.dr.dk/cms/mp4:CMS/Resources/dr.dk/NETTV/DR1/2011/09/18a5c2f8-8802-4de6-9a9d-6b337b95e1ad/Bonderoeven--5-10---7--saeson-_32f7289ed4f9472c805711dfd91fbf90.mp4?ID=983628",
"linkType":"Streaming",
"fileType":"mp4",
"bitrateKbps":1126,
"width":640,
"height":360
},
{
"qualityId":2350583,
"uri":"rtmp://vod.dr.dk/cms/mp4:CMS/Resources/dr.dk/NETTV/DR1/2011/09/18a5c2f8-8802-4de6-9a9d-6b337b95e1ad/Bonderoeven--5-10---7--saeson-_32f7289ed4f9472c805711dfd91fbf90_1.mp4?ID=983628",
"linkType":"Streaming",
"fileType":"mp4",
"bitrateKbps":626,
"width":640,
"height":360
},
{
"qualityId":2350584,
"uri":"rtmp://vod.dr.dk/cms/mp4:CMS/Resources/dr.dk/NETTV/DR1/2011/09/18a5c2f8-8802-4de6-9a9d-6b337b95e1ad/Bonderoeven--5-10---7--saeson-_32f7289ed4f9472c805711dfd91fbf90_2.mp4?ID=983628",
"linkType":"Streaming",
"fileType":"mp4",
"bitrateKbps":376,
"width":320,
"height":180
}
],
"chapters":[],
"productionNumber":"00951134130"
}

Hvor der tydeligvis er en indgang for hver kvalitet. DVS at URLen for den højeste kvalitet er rtmp://vod.dr.dk/cms/mp4:CMS/Resources/dr.dk/NETTV/DR1/2011/09/18a5c2f8-8802-4de6-9a9d-6b337b95e1ad/Bonderoeven--5-10---7--saeson-_32f7289ed4f9472c805711dfd91fbf90.mp4?ID=983628
hvor delen efter ":" er en playpath. Den kan downloades med Linux-programmet rtmpdump med kommandoen
rtmpdump --playpath="mp4:CMS/Resources/dr.dk/NETTV/DR1/2011/09/18a5c2f8-8802-4de6-9a9d-6b337b95e1ad/Bonderoeven--5-10---7--saeson-_32f7289ed4f9472c805711dfd91fbf90.mp4?ID=983628" -r 'rtmp://vod.dr.dk/cms/mp4:CMS/Resources/dr.dk/NETTV/DR1/2011/09/18a5c2f8-8802-4de6-9a9d-6b337b95e1ad/Bonderoeven--5-10---7--saeson-_32f7289ed4f9472c805711dfd91fbf90.mp4?ID=983628' -o br.flv

Tak til marlar i tråden http://www.linuxin.dk/node/17903 for at finde ud af playpath-delen!

Vi mangler stadig at finde links til de gamle afsnit, og til det skal vi gætte {slug} i URLerne. For at finde {slug} for Bonderøven kigger jeg på programseriernes links nederst på siden http://www.dr.dk/nu , og kan se at de er af formen http://www.dr.dk/nu/player/#/bonderoeven/18431 eller http://www.dr.dk/nu/player/#/bonderoeven-retro/13380 . Så siden 18431 var et videoId, gætter jeg på at "bonderoeven" er {slug}. Og ganske rigtigt, så giver http://www.dr.dk/nu/api/programseries/bonderoeven/images/1000x1000.jpg og http://www.dr.dk/nu/api/programseries/bonderoeven/videos et logo samt en liste over episoder med tilhørende downloadlinks.

mandag den 11. januar 2010

PHP's implementation of fgetcsv() and fputcsv() does not follow RFC 4180 or Wikipedia's description, and does not work in all cases with Excel or OO Calc, as described in bug http://bugs.php.net/bug.php?id=50686 .

Here is an RFC 4180-complient implementation in PHP. This can parse more than 1MiB of CSV text per second, so should be fast enough for most uses. It is fairly strict, in that it does not allow whitespace before the start of a quoted item, such as 1, "2" ,3 , in according to the standard, but it would be simple to make it laxer. It supports both \r\n and \n linebreaks, where the standard only supports \r\n. whitespace is just another data character, so '1, 2,3 ' becomes Array(1, " 2", "3 "). backslashes are also just another character, as backslashes have no special meaning in RFC 4180.

The code below may be used and redistributed without restrictions. You may consider buying me a beer if you find it useful.


class csv {

private static function error($error, $str, $m, $offset, $moving_offset, $csv_line) {
if ($error === "unexpected quote in unquoted field") {
$raw = _("Found an unexpected quote character in field %d of csv line %d (text line %d).".
" The first 50 chars from the start of the field are '%s'.");
} else if ($error === "unexpected quote in quoted field") {
$raw = _("Found an unescaped quote in quoted field %d of csv line %d (text line %d).".
" The first 50 chars from the start of the field are '%s'.");
} else if ($error === "unexpected text after end quote in quoted field") {
$raw = _("Unexpected test after end quote in quoted field %d of csv line %d (text line %d).".
" The first 50 chars from the start of the field are '%s'.");
} else {
die("impossible");
}

$t = sprintf($raw,
sizeof($m[$csv_line])+1,
$csv_line,
sizeof(explode("\n", substr($str, 0, $offset))),
addcslashes(substr($str, $offset, 50), "\t\r\n'\\")
);
throw new Exception($t);
}

/* returns
* array(start_line1 => Array(field1, field2,...),
* start_line2 =>
* ...);
*
* Faily speed-important, therefore:
* -With few function calls.
* -Never copy the entire (potentially MB-long) string
* -Never operate on the whole string (so therefore we use no pregs)
*
* This implementation parses a 1MB csv file in under a second,
* which is obviously slow, but should be fast enough. My first try
* was using regexp_max with regexp's offset parameter, which failed
* horribly speed-wise.
*
* The basic idea is to eat one char at a time, and append fields
* and lines to the matrix as we encounter separators and newlines.
*
* Not using PHP's fgetcsvdue to http://bugs.php.net/bug.php?id=50686
*/
public static function parse($str, $sep=',') {
if ($str === "") {
return Array();
}

$str .= "\r\n";
$offset = 0;
$item = "";
$len = strlen($str);
$csv_line = 1;
$m = Array($csv_line => Array());
$force_empty_field = false;

$moving_offset = 0;
while ($moving_offset < $len) {
$c = $str[$moving_offset];
if ($c === $sep) {
//separator
$m[$csv_line][] = $item;
$item = "";
$force_empty_field = true;
$offset = ++$moving_offset;
} else if ($c === "\n") {
//newline
if ($str[$moving_offset -1] === "\r") {
//The \r belonged to the newline
$item = substr($item, 0, -1);
}
if ($item !== "" || $force_empty_field) {
$m[$csv_line][] = $item;
$item = "";
}
$offset = ++$moving_offset;

//end of string
if ($offset === $len) {
return $m;
}

$m[++$csv_line] = Array();
$force_empty_field = false;
} else if ($c === '"') {
//quoted item

if ($item !== "") {
//throws exception
self::error("unexpected quote in unquoted field",
$str, $m, $offset, $moving_offset, $csv_line);
}

//eat quote
$moving_offset++;

//read until end quote
while (true) {
$c = $str[$moving_offset];

if ($moving_offset >= $len) {
//throws exception
self::error("unexpected quote in quoted field",
$str, $m, $offset, $moving_offset, $csv_line);
}
if ($c === '"') {
if ($str[$moving_offset+1] === '"') {
//escaped quote
$item .= '"';
$moving_offset += 2; //eat doubled quotes
} else {
//end of item
$moving_offset++; //eat end quote
break;
}
} else {
$item .= $c;
$moving_offset++;
}
}

//eat separator
if ($str[$moving_offset] === $sep) {
$force_empty_field = true;
$moving_offset++;
} else if ( ($str[$moving_offset] === "\r" && $str[$moving_offset+1] === "\n")
|| $str[$moving_offset] === "\n") {
$force_empty_field = false;
} else {
self::error("unexpected text after end quote in quoted field",
$str, $m, $offset, $moving_offset, $csv_line);
}

//add field and reset for next field
$m[$csv_line][] = $item;
$item = "";
$offset = $moving_offset;
} else {
$moving_offset++;
$item .= $c;
}
}

die("impossible, since the last char is a \n, and the newline handling should catch that");
}

public static function matrix_to_csv(Array $matrix, $sep=',') {
$str = "";
foreach ($matrix as $row) {
if ($str !== "") {
$str .= "\r\n"; //not just \n, according to RFC 4180
}

$row = array_map(Array(__CLASS__, "escape"), $row);
$row_str = implode($sep, $row);
$str .= $row_str;
}

return $str;
}
}

?>

mandag den 16. november 2009

Sid Meier's Alpha Centauri on Linux

I own Sid Meier's Alpha Centauri Planetary Pack in the Linux edition from Loki. However, it unfortunately does not seem to run on a modern Linux distribution.

So I decided to make a virtual machine image of an old Linux distribution to make it work. That way I will never have to reinstall it, as long as I save the virtualized image.

So the procedure is:
1) Download Red Hat 8 (in 2 disks): ftp://ftp.gmd.de/archive.download.redhat.com/redhat/linux/8.0/en/iso/i386/psyche-i386-disc1.iso and ftp://ftp.gmd.de/archive.download.redhat.com/redhat/linux/8.0/en/iso/i386/psyche-i386-disc2.iso.

2) Create a virtual disk image:
emu-img create -f qcow2 smac_redhat8.img 5G

3) Optionally install kqemu kernel module to accelerate qemu (Red Hat 8 didn't work with kvm,presumably because my CPU is not known by Red Hat 8).

3) Install Red Hat 8 in virtual image:
qemu -cpu pentium2 -hda smac_redhat8.img -m 1024 -soundhw ac97 -cdrom psyche-i386-disc1.iso
(You change cdrom in qemu by CTRL-ALT-2 and then "change ide1-cdrom psyche-i386-disc2.iso")
Inside the redhat install just selected a generic monitor, which happened to have a default resolution of 1024x768, which happened to be the max resolution of SMAC.
Inside the finished installation you need to add "options i810_audio clocking=48000" to /etc/modules.conf , otherwise the sound will play too slowly, and in a very low pitch.

4) I think you need to tell qemu to use ALSA instead of OSS:
export QEMU_AUDIO_DRV=alsa
export QEMU_AUDIO_DAC_FIXED_FREQ=48000
export QEMU_AUDIO_ADC_FIXED_FREQ=48000


5) Install SMAC inside the virtual machine by putting my SMAC cd in the cd drive, and booting qemu with "-cdrom /dev/cdrom". I just installed SMAC as root inside the virtual machine, as the default install settings expected that. SMAC will be in the main menu under extras->games->smac.

6) Update SMAC. Since none of the mirrors the loki update tool knew worked (and I did not want to set up virtual networking), I manually fetched http://lokifiles.tuxgames.com/updates/smac/smac-6.0a-x86.run , made it into an iso image ("genisoimage -o smac_patch.iso dir_with_smac-6.0a-x86.run"), and mounted smac_patch.iso as a cdrom in qemu. You can then run smac-6.0a-x86.run (as root) to patch the SMAC installation.

7) You can the virtual machine in full screen mode by hitting CTRL-ALT-f

søndag den 10. maj 2009

Hardcover Books and Market Segmentation

New books are usually only available in hardcover for about a year.

Wikipedia writes that
Hardcover books tend to cost more than paperback versions of the book. This is due to price discrimination by booksellers who observe that consumers are willing to pay a premium for hardcover editions over paperbacks beyond the extra costs in materials and production.
This bugs me. I think that for most for-fun reading where you aren't taking notes, paperbacks are ergonomically better. So not only do I have to pay more, I am paying more for an inferior product. If they do insist on charging more for new books (fair enough), at least make it an expensive paperback.